Robin Laurenssen Robin Laurenssen - 1 month ago 10
iOS Question

How do i replace array values with a UISwitch

Im making an interactive soundboard app that plays 1 of the 6 sounds after a button is pushed and a shake gesture. It worked fine till i wanted to add a switch that replaces the 6 sounds with 6 others and i just can't get it to replace the array values with new ones. The background changes color though so the switch works.

edit: so it just needs to change the array soundFilenames values when the switch is turned off and on. So it can switch between the two sets of sounds. But its not changing the values and i can't get it to work

class ViewController: UIViewController {

var soundFilenames = ["dbzexplo", "explo2", "ooohh", "wow", "anotherOne", "teleport"]
var audioPlayers = [AVAudioPlayer]()
var afspelen: AVAudioPlayer!

@IBOutlet var background: UIView!
@IBOutlet weak var switchVar: UISwitch!
@IBAction func switchCode(_ sender: AnyObject) {
if switchVar.isOn{
background.backgroundColor = UIColor.green
soundFilenames = ["bla5", "bla4", "bla3", "bla2", "bla", "scifi002"]
}
else{
background.backgroundColor = UIColor.black
soundFilenames = ["dbzexplo", "explo2", "ooohh", "wow", "anotherOne", "teleport"]
}

}


override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

//audio players setup
for sound in soundFilenames {

do{
let url = URL(fileURLWithPath: Bundle.main.path(forResource: sound, ofType: "wav")!)
let audioPlayer = try AVAudioPlayer(contentsOf: url)

audioPlayers.append(audioPlayer)
}
catch{
audioPlayers.append(AVAudioPlayer())
}

}
}

@IBAction func buttonTapped(_ sender: UIButton) {
let image = UIImage(named: "geel")
let image2 = UIImage(named: "grey")
let buttonsArray: Array<UIButton> = [b1, b2, b3, b4, b5, b6]

for index in buttonsArray {
index.setImage(image2, for: .normal)
}

afspelen = audioPlayers[sender.tag]
sender.setImage(image, for: .normal)
}

override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
afspelen.play()
}


}

Answer

You are changing the sound names but not the audio players.

Create a method setupSounds()

func setupSounds()
  {
    audioPlayers.removeAll()
    for sound in soundFilenames {
      do {
        if let url = Bundle.main.url(forResource: sound, withExtension: "wav") {
           let audioPlayer = try AVAudioPlayer(contentsOf: url)
           audioPlayers.append(audioPlayer)
        }
      }
      catch{
        audioPlayers.append(AVAudioPlayer())
      }
    }
  }

Reduce viewDidLoad to

override func viewDidLoad() {
   super.viewDidLoad()
   setupSounds()
 }

And call setupSounds() also at the end of the switchCode method.


Alternatively there is a swiftier way:

Declare soundFilenames as empty array and implement the didSet observer:

var soundFilenames = [String]() {
   didSet {
       audioPlayers.removeAll()
       for sound in soundFilenames {
         do {
           if let url = Bundle.main.url(forResource: sound, withExtension: "wav") {
              let audioPlayer = try AVAudioPlayer(contentsOf: url)
              audioPlayers.append(audioPlayer)
           }
         }
         catch {
           audioPlayers.append(AVAudioPlayer())
         }
       }
    }
 }

Assuming the switch is off by default call switchCode in viewDidLoad, that's all.

override func viewDidLoad() {
   super.viewDidLoad()
   switchCode(self)
 }

Now every time soundFilenames is changed the players are recreated.

Comments