Sami Smadi
Sami Smadi

Reputation: 101

Play specific sound when specific button is pressed in iOS

I'm a beginner in iOS development and I am trying to make a simple app which plays specific sounds when a specific button is pressed with two segmented control for options (as shown in the image below). I have looked up many tutorials on YouTube, stack and other websites, but all of them seem to either give me a lot of errors or are too hard for me too understand (as I am too unexperienced).

Some of my attempts, but this work for 1 button and 1 sound only.

import UIKit
import AVFoundation

class ViewController: UIViewController {
    // make sure to add this sound to your project
    var pianoSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("C", ofType: "m4a"))
    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        audioPlayer = AVAudioPlayer(contentsOfURL: pianoSound, error: nil)
        audioPlayer.prepareToPlay()
    }

    @IBAction func PianoC(sender: AnyObject) {
        audioPlayer.play()
    }
}

Please, can someone show me how to make this app, as shown in the image below?

https://i.sstatic.net/VdSnR.jpg

Required: there are three buttons ( cat, dog, bird ) , every button have own sound. and the first segmented ( sound ) for enable or disable the sound, eg. when user choose sound off option there will be no sound even the button clicked, and the second segmented for enable or disable the music on the background .

Upvotes: 0

Views: 4452

Answers (2)

Duncan C
Duncan C

Reputation: 131398

So create a method that plays a sound by name, and have each button action call that method. Also have each method check the state of your play sound switch before beginning to play that sound.

@IBOutlet weak playSoundSwitch: UISwitch!

var backgroundMusicPlayer: AVAudioPlayer?

@discardableResult func playSound(named soundName: String) -> AVAudioPlayer {
    var soundURL = NSURL(fileURLWithPath: 
      NSBundle.mainBundle().pathForResource(soundName, ofType: "m4a"))
    audioPlayer = AVAudioPlayer(contentsOfURL: soundURL, error: nil)
    ( it MUST be a class variable )
    audioPlayer.play()
    return audioPlayer
}

@IBAction func catButtonPressed(sender: AnyObject) {
  if playSoundSwitch.isOn {
    playSound("catSound")
  }
}

@IBAction func dogButtonPressed(sender: AnyObject) {
  if playSoundSwitch.isOn {
    playSound("dogSound")
  }
}

@IBAction func birdButtonPressed(sender: AnyObject) {
  if playSoundSwitch.isOn {
    playSound("birdSound")
  }
}

@IBAction func playBackgroundMusicSwitchChanged(sender: UISwitch) {
  if sender.isOn {
    backgroundMusicPlayer = playSound("backgroundSound")
  } else {
    backgroundMusicPlayer?.stop()
    backgroundMusicPlayer = nil
  }
}

The above assumes that your background music sound is long enough to last for the entire session. If you need to repeat the sound each time it ends it would be more complicated. You'd have to set yourself up as the delegate of the sound player and restart it each time it ended. You'd use the audioPlayerDidFinishPlaying(_:successfully:) delegate method.

If you want the play sound switch to terminate the current sound early, you'd need to add logic to handle that. Likewise if you want to only allow one animal sound at a time you'd have to add logic for that.

(The code above was banged out in the SO editor. It likely contains minor syntax errors that will need to be cleaned up. It's only meant as a guide, not copy/paste code.)

latest syntax ..

import AVFoundation
class yourClass {
    var _sfx: AVAudioPlayer? // IT >MUST< BE a class variable
    func sound(named: String) {

        let u = Bundle.main.path(forResource: named, ofType: "m4a")!
        let s = URL(fileURLWithPath:u)
        do {
            _sfx = try AVAudioPlayer(contentsOf: s)
            _sfx.play()

            // note, you >CAN NOT< say here ..
            // let variable = try AVAudioPlayer(contentsOf: s)
            // IT >MUST< BE a class variable
        }
        catch { print("WOE!"); return }
        print("PLAYED \(named)")
    }

Upvotes: 2

Sami Smadi
Sami Smadi

Reputation: 101

import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var playSoundSwitch: UISegmentedControl!

    var backgroundMusicPlayer: AVAudioPlayer?

    var player:AVAudioPlayer = AVAudioPlayer()

    @discardableResult func playSound(named soundName: String) -> AVAudioPlayer {


        let audioPath = Bundle.main.path(forResource: soundName, ofType: "wav")
        player = try! AVAudioPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL)
        player.play()
        return player
    }


    @IBAction func catButtonPressed(_ sender: Any) {

        if playSoundSwitch.selectedSegmentIndex == 0 {
            playSound(named: "catSound")
        }


    }

    @IBAction func dogButtonPressed(_ sender: Any) {
        if playSoundSwitch.selectedSegmentIndex == 0 {
            playSound(named: "dogSound")
        }
    }

    @IBAction func birdButtonPressed(_ sender: Any) {

        if playSoundSwitch.selectedSegmentIndex == 0 {
            playSound(named: "birdSound")
            print("bird sound")
        }
    }

    @IBAction func playBackgroundMusicSwitchChanged(_ sender: Any) {


        if (sender as AnyObject).selectedSegmentIndex == 0 {
            backgroundMusicPlayer = playSound(named: "backgroundSound")
        } else {
            backgroundMusicPlayer?.stop()
            backgroundMusicPlayer = nil
        }
    }

}

Upvotes: 1

Related Questions