How to play sound, when backBarButton (from NavigationController) is pressed? (for Swift)

174 views Asked by At

Can't find out how to add playing sound, when back button in my NavigationController is pressed.

I have some VCs in NavigationVC. I didn't customise NavigationVC, but I've set back button for NavigationVC in the first VC on its stack. I'm trying to add func playing sound in the action of this button. But it doesn't call.

Here's my code. This is the first ViewController for NavigationVC:

override func viewDidLoad() {
    super.viewDidLoad()

    // some another code

    // set back button for Navigation Controller
    self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "backButtonIcon")
    self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "backButtonIcon")
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItem.Style.plain, target: self, action: #selector(backButtonPressed))
    self.navigationItem.backBarButtonItem?.action = #selector(backButtonPressed)
}

// this func isn't called, but has to be
@objc func backButtonPressed() {
    print("back button pressed")
    Sounds.playSound(Sounds.tap)
}

Here is Sounds. This is struct in AppDelegate file. I use static properties and functions, so I don't create instance of this struct;

struct Sounds {
static let lose = Bundle.main.url(forResource: "lose", withExtension: "mp3")
static let win = Bundle.main.url(forResource: "win", withExtension: "mp3")
static let select = Bundle.main.url(forResource: "select", withExtension: "mp3")
static let deSelect = Bundle.main.url(forResource: "unSelect", withExtension: "mp3")
static let tap = Bundle.main.url(forResource: "tap", withExtension: "mp3")

static var soundsIsDisabled = UserDefaults.init().bool(forKey: "sounds is disabled") {
    didSet {
        UserDefaults.init().set(soundsIsDisabled, forKey: "sounds is disabled")
    }
}

static func playSound(_ sound: URL?) {
    if !Sounds.soundsIsDisabled {
        guard let url = sound else { return }

        do {
            AppDelegate.audioPlayer = try AVAudioPlayer(contentsOf: url)
            try AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default, options: .defaultToSpeaker)
            try AVAudioSession.sharedInstance().setActive(true)
            AppDelegate.audioPlayer.prepareToPlay()
        }
        catch{
            print(error)
        }

        AppDelegate.audioPlayer.play()
    }
}

}

My goal, as you can see, is to add tap sound on backButtons for all VCs in NavigationVC.

How can achieve it?

1

There are 1 answers

0
Nikita Goncharov On BEST ANSWER

I found a solution in the post sent in the comments. This post

I didn't fully understand, what's exactly happening there (because there was Objective-C code).

So, the solution is to create a custom leftBarButtonItem instead of backBarButtonItem and add this button in every VC in NavigationVC you need this button to be.

Here is code you have to add in every VC:

override func viewDidLoad() {
    super.viewDidLoad()

    //some other code

    self.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "backButtonIcon"), style: UIBarButtonItem.Style.plain, target: self, action: #selector(backButtonPressed))
}

@objc func backButtonPressed() {

    // implement your action here
}