英文:
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
听起来最好在ViewController
的viewWillAppear
方法中读取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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论