Reputation: 25
How to make a "activate / deactivate background music" button in my settings?
Music is only played when the game's launched. (Tap "Start" to play -> Background music is played too.)
I have coded this for the moment but I really do not know how to do it.
class SettingsViewController: UITableViewController {
// MARK: - IBOutlets
@IBOutlet weak var backgroundgMusicLabel: UILabel!
@IBOutlet weak var backgroundMusicSwitch: UISwitch!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func backgroundMusicPressed(_ sender: Any) {
if backgroundMusicSwitch.isOn {
UserDefaults().set("On", forKey: "switch")
} else {
UserDefaults().set("Off", forKey: "switch")
}
}
}
While I've this code in my MainViewController:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if game == .ready {
start()
}
}
And I play music like this:
var audioPlayer: AVAudioPlayer?
func playMusic() {
let url = Bundle.main.url(forResource: "MyMusic", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
guard let audioPlayer = audioPlayer else { return }
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch let error {
print(error.localizedDescription)
}
}
Upvotes: 2
Views: 359
Reputation: 411
TheValyreanGroup is right with Globals.
class Globals: NSObject {
static let sharedInstance = Globals()
var audioPlayer: AVAudioPlayer?
func playMusic() {
let url = Bundle.main.url(forResource: "MyMusic", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
guard let audioPlayer = audioPlayer else { return }
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch let error {
print(error.localizedDescription)
}
}
}
But in your case try the following code:
MainViewController:
static let sharedInstance = Globals()
let globalVars = Globals.sharedInstance
And add this func in your start() function:
func checkMusicStatus() {
let status = UserDefaults().string(forKey: "switch")
if status == "Off"{
if (self.globalVars.audioPlayer?.isPlaying != nil){
self.globalVars.audioPlayer?.stop()
}
} else {
self.globalVars.playMusic()
}
}
It should work, hope this will help.
Upvotes: 2
Reputation: 3599
When i need to do something like this i like to use a SharedInstance
class. Some poeple call it a singleton, but i don't believe it actually is.
Create a new swift file and name it something like 'Globals'. Declare any variables or objects you'll want to share between VC's here and you can also create global functions as well. Keep in mind, these are all going to be the same instance. It's not the same as passing a variable between VC's or grabbing another instance of another VC.
Globals.swift
class Globals: NSObject {
static let sharedInstance = Globals()
var audioPlayer: AVAudioPlayer?
func playMusic() {
let url = Bundle.main.url(forResource: "MyMusic", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
guard let audioPlayer = audioPlayer else { return }
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch let error {
print(error.localizedDescription)
}
}
}
Now, in any of your VC's, you declare a class scope variable of this new Globals class and use any of the objects from it by prepending globalVars
class SettingsViewController: UITableViewController {
// MARK: - IBOutlets
@IBOutlet weak var backgroundgMusicLabel: UILabel!
@IBOutlet weak var backgroundMusicSwitch: UISwitch!
let globalVars = Globals.sharedInstance()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func backgroundMusicPressed(_ sender: Any) {
if backgroundMusicSwitch.isOn {
UserDefaults().set("On", forKey: "switch")
self.globalVars.audioPlayer.play() //Uses the same instance of the audioPlayer you created in the 'Globals' class
} else {
UserDefaults().set("Off", forKey: "switch")
self.globalVars.audioPlayer.stop()
}
}
}
Since your playMusic
function has moved to this new class, you'll call it the same way.
self.globalVars.playMusic()
I know a lot of people frown upon using so called 'global variables', however, i find this shared instance class extremely useful in many scenarios. Especially games. This is also how i keep a "running" class of all my extensions, subclasses, custom functions that can be repurposed, etc. I just include this same file in all of my projects and can access all of my favorite functions immediately.
Upvotes: 1