有没有一种方法可以保存UIButton的“selected”状态?

huangapple go评论73阅读模式
英文:

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

问题

我正在为儿童创建一个拼图游戏应用,其中包含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)
            audioPlayerBGM!.numberOfLoops = -1
            audioPlayerBGM!.prepareToPlay()
            audioPlayerBGM!.play()
            audioPlayerBGM!.volume = 0.1
        } catch {
            print("无法播放文件")
        }
    }
    
    func pauseBackgroundMusic() {
        let BGM = URL(fileURLWithPath: Bundle.main.path(forResource: "jigsawBGM", ofType: "wav")!)
        do {
            audioPlayerBGM = try AVAudioPlayer(contentsOf: BGM)
            audioPlayerBGM!.pause()
        } catch {
            print("无法播放文件")
        }
    }
}

为了父母的健康,我还编写了一段静音背景音乐的代码,如下所示:

@IBOutlet weak var muteMusicButton: UIButton!

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

我已将静音音乐按钮放在一个单独的视图控制器场景中(类似于应用用户的“控件”或“设置”窗口)。它是一个自定义按钮,具有默认状态(“音乐开启”图像)和选定状态(“音乐关闭”图像)的不同图像。

问题是,当关闭其视图控制器时,按钮会重置为默认状态,因此当您再次访问视图控制器时,音乐仍然处于暂停状态,但按钮显示“音乐开启”图像,您必须按两次才能重新开始音乐。

是否有一种方法可以使按钮在关闭/重新访问其视图控制器时“记住”其选定状态?
(也许可以使用UserDefaults,但我对此非常无能!)

或者,我应该完全以不同的方式处理整个事情?

英文:

I'm creating a jigsaw puzzle app for kids with 24 different little puzzles in 24 different scenes. I've put the background music in a Singleton, like so:

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")
        }
    }
}

For the sake of parents' sanity, I've also written a snippet of code to mute the BGM. Like so:

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

I've put the muteMusicButton in a separate view controller scene (like a 'controls' or 'settings' window for the app user). It's a custom button with different images for default state ('music on' image) and selected state ('music off' image).
The problem is that the button resets to default state when its view controller is dismissed, so that when you access the view controller again music is still paused, but the button displays the 'music on' image, and you have to press it twice to start the music again.

Is there a way to make to make a button 'remember' its selected state when you dismiss/re-access its view controller?
(UserDefault perhaps, which I am notoriously incompetent at!)

Or should I go about the whole thing in a completely different manner?

答案1

得分: 1

不要回答我要翻译的问题。

以下是要翻译的内容:

"Instead of saying "I'm rubbish at UserDefault" take a little time to learn about it.

Very briefly, though...

Decide on a "key" for your setting -- let's use "isMuted"

When you're going to start playing music, read the value of that key from UserDefaults:

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

When you show your "settings" view controller (in viewDidLoad for example), read that value and set the button's isSelected property:

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

When the user taps the button, write the new value to UserDefaults (based on your code):

@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()
    }
}"
英文:

Instead of saying "I'm rubbish at UserDefault" take a little time to learn about it.

Very briefly, though...

Decide on a "key" for your setting -- let's use "isMuted"

When you're going to start playing music, read the value of that key from UserDefaults:

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

When you show your "settings" view controller (in viewDidLoad for example), read that value and set the button's isSelected property:

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

When the user taps the button, write the new value to UserDefaults (based on your code):

@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()
	}
}

答案2

得分: 0

听起来最好在ViewControllerviewWillAppear方法中读取isPlaying属性,以相应地更新按钮状态。

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

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

Sounds like would be best to read the isPlaying property at viewWillAppear of the ViewController to update the button state accordingly.

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

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

答案3

得分: 0

使用以下代码将Bool值存储到UserDefaults中:

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

使用以下代码从UserDefaults中读取您的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") // 在这里
        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")  // 在这里
     } else {
        MusicHelper.sharedHelper.playBackgroundMusic()
        UserDefaults.standard.set(true, forKey: "isMuted")  // 在这里
     }
}
func viewWillAppear() {
   muteMusicButton.isSelected = UserDefaults.standard.bool(forKey: "isMuted")
}
英文:

Use this to store a Bool to UserDefaults:

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

Use this to read back your Bool:

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

In your example:

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")
}

huangapple
  • 本文由 发表于 2023年7月20日 16:16:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定