有没有办法保存UIButton的“选定”状态?

Is there a way to save 'selected' state of a UIButton?

提问人:KrisP 提问时间:7/20/2023 最后编辑:HangarRashKrisP 更新时间:7/23/2023 访问量:80

问:

我正在为孩子们创建一个拼图游戏应用程序,在 24 个不同的场景中提供 24 个不同的小拼图。我把背景音乐放在一个单例中,就像这样:

class MusicHelper { static let sharedHelper = MusicHelper() var audioPlayerBGM: AVAudioPlayer?
    func playBackgroundMusic() {
        let BGM = URL(fileURLWithPath: Bundle.main.path(forResource: "jigsawBGM", ofType: "wav")!)
        do {
            audioPlayerBGM = try AVAudioPlayer(contentsOf:BGM as URL)
            audioPlayerBGM!.numberOfLoops = -1
            audioPlayerBGM!.prepareToPlay()
            audioPlayerBGM!.play()
            audioPlayerBGM!.volume = 0.1
        } catch {
            print("Cannot play the file")
        }
    }
    
    func pauseBackgroundMusic() {
        let BGM = URL(fileURLWithPath: Bundle.main.path(forResource: "jigsawBGM", ofType: "wav")!)
        do {
            audioPlayerBGM = try AVAudioPlayer(contentsOf:BGM as URL)
            audioPlayerBGM!.pause()
        } catch {
            print("Cannot play the file")
        }
    }
}

为了家长的理智,我还写了一段代码来静音BGM。这样:

@IBOutlet weak var muteMusicButton: UIButton!
@IBAction func muteMusic(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
 
    if muteMusicButton.isSelected {
        MusicHelper.sharedHelper.pauseBackgroundMusic()
    } else {
        MusicHelper.sharedHelper.playBackgroundMusic()
    }
}

我已将muteMusicButton放在单独的视图控制器场景中(例如应用程序用户的“控件”或“设置”窗口)。这是一个自定义按钮,具有默认状态(“音乐开启”图像)和选定状态(“音乐关闭”图像)的不同图像。 问题在于,当其视图控制器被关闭时,按钮会重置为默认状态,因此当您再次访问视图控制器时,音乐仍处于暂停状态,但该按钮显示“音乐开启”图像,您必须按两次才能再次启动音乐。

有没有办法让按钮在关闭/重新访问其视图控制器时“记住”其选择状态? (也许是UserDefault,我是出了名的无能!

还是我应该以完全不同的方式处理整个事情?

iOS Swift UIBuint

评论

0赞 Joakim Danielson 7/20/2023
UserDefaultS 在这里是一个很好的解决方案,因为应用程序可以在下次打开时“记住”状态
0赞 KrisP 7/20/2023
是的,这可能是一个很好的解决方案,我真的很垃圾。我在这里看过答案:stackoverflow.com/questions/43429699/......但没有什么对我有用。你有什么建议吗?
0赞 DonMag 7/20/2023
@KrisP - 您是否已经在应用程序使用之间保存了用户的选择?也就是说,如果用户关闭了音乐,你是否已经对应用进行了编码,以便在下次运行时关闭音乐?
0赞 KrisP 7/20/2023
@DonMag:没有。UserDefault 不会也这样做吗?就像我说的,我在 UserDefault 上是垃圾 - 但我现在正在阅读它。我决定不让它赢:-)

答:

0赞 humi.dev 7/20/2023 #1

听起来最好读取 的属性,以相应地更新按钮状态。isPlayingviewWillAppearViewController

https://developer.apple.com/documentation/avfaudio/avaudioplayer/1390139-isplaying

override func viewWillAppear(_ animated: Bool) {
   muteMusicButton.selected = !MusicHelper.sharedHelper.audioPlayerBGM.isPlaying
}

评论

0赞 KrisP 7/20/2023
这不会改变任何事情......
0赞 humi.dev 7/21/2023
已更新:您需要覆盖生命周期方法...
0赞 HangarRash 7/22/2023
必须在重写的方法内部调用。super.viewWillAppear(animated)
1赞 DonMag 7/20/2023 #2

与其说“我在UserDefault是垃圾”,不如花一点时间了解它

不过,非常简短......

为您的设置确定一个“键”——让我们使用“isMuted”

当您要开始播放音乐时,请从以下位置读取该键的值:UserDefaults

let b: Bool = UserDefaults.standard.bool(forKey: "isMuted")
if b {
    // don't play the music
} else {
    // play the music
}

当您显示“设置”视图控制器(例如)时,请读取该值并设置按钮的属性:viewDidLoadisSelected

let b: Bool = UserDefaults.standard.bool(forKey: "isMuted")
muteMusicButton.isSelected = b

当用户点击按钮时,将新值写入(基于代码):UserDefaults

@IBAction func muteMusic(_ sender: UIButton) {
    
    sender.isSelected = !sender.isSelected

    UserDefaults.standard.set(sender.isSelected, forKey: "isMuted")
    
    if muteMusicButton.isSelected {

        MusicHelper.sharedHelper.pauseBackgroundMusic()
    }

    else {

        MusicHelper.sharedHelper.playBackgroundMusic()
    }
}

评论

0赞 KrisP 7/21/2023
从你的高头大马上下来,阅读我说我正在阅读它的评论!
1赞 DonMag 7/21/2023
@KrisP - 对不起...我本来想让这听起来令人鼓舞,而不是批评。
0赞 soundflix 7/20/2023 #3

使用它来存储 UserDefaults:Bool

UserDefaults.standard.set(false, forKey: "isMuted")

使用它来回读你的:Bool

let isMuted = UserDefaults.standard.bool(forKey: "isMuted")

在您的示例中:

class MusicHelper {
    static let sharedHelper = MusicHelper()
    var audioPlayerBGM: AVAudioPlayer?

    init() {
        let BGM = URL(fileURLWithPath: Bundle.main.path(forResource: "jigsawBGM", ofType: "wav")!)
        audioPlayerBGM = try? AVAudioPlayer(contentsOf: BGM)
        audioPlayerBGM?.numberOfLoops = -1
        audioPlayerBGM?.volume = 0.1
        audioPlayerBGM?.prepareToPlay()

         let isMuted = UserDefaults.standard.bool(forKey: "isMuted") // here
         if !isMuted {
             audioPlayerBGM?.play()
         }
    }

    func playBackgroundMusic() {
        audioPlayerBGM?.play()
    }

    func pauseBackgroundMusic() {
        audioPlayerBGM?.pause()
    }
}
@IBOutlet weak var muteMusicButton: UIButton!

@IBAction func muteMusic(_ sender: UIButton) {

    sender.isSelected = !sender.isSelected
 
    if muteMusicButton.isSelected {
        MusicHelper.sharedHelper.pauseBackgroundMusic()
        UserDefaults.standard.set(false, forKey: "isMuted")  // here
     } else {
        MusicHelper.sharedHelper.playBackgroundMusic()
        UserDefaults.standard.set(true, forKey: "isMuted")  // here
     }
}

func viewWillAppear() {
   muteMusicButton.isSelected = UserDefaults.standard.bool(forKey: "isMuted")
}