tvosapple-tvsiri-remote

unable to intercep Pause button on SiriRemote - always stops the background music and never resumes it


I am trying to use Pause button on the SiriRemote to pause my game (SpriteKit, one ViewController, multiple SKScenes).

I am using the same method as I did for Menu button:

  1. override pressesBegan and pressesEnded in my GameViewController
  2. pass the UIPressType.PlayPauseUIPressType.PlayPause events to the current scene, accessed via skView.scene! as! PilotButtonDelegate (this is my delegate for handling those damn buttons)
  3. In my scenes I process the event and return Bool back to GameViewController advising pressesBegan and pressesEnded to call super.pressesBegan (or Ended) or not depending whether I have handled this in my Scene or not.

Above works like charm for Menu (I navigate through scenes nicely) but Pause does somehow propagate back to the TVOS and pauses my background music even if I do intercept it (i.e. do not call super). Any ideas what am I doing wrong?

What is surprising pressing PlayPause again does not start the music.

PS. I have checked and the same behavior (e.g. music pauses but does not resume) occurs when I use PlayPause button in any other app (e.g. Search / Computers, Photos).


Solution

  • to elaborate on my comment above, this is how it could look depending on what kind of gestures you want/need. Advantage with recognizers is that you can add them to any SKScene instead of managing button presses through the gameViewController and delegates/protocols. Its much easier and works great.

    func loadTVGameControls() {
    
        // main (select) button
        let tapMain = UITapGestureRecognizer()
        tapMain.addTarget(self, action: "pressedTVRemoteSelectButton")
        tapMain.allowedPressTypes = [NSNumber (integer: UIPressType.Select.rawValue)]
        self.view!.addGestureRecognizer(tapMain)
    
        // play pause
        let tapPlayPause = UITapGestureRecognizer()
        tapPlayPause.addTarget(self, action: "pressedTVRemotePlayPauseButton")
        tapPlayPause.allowedPressTypes = [NSNumber (integer: UIPressType.PlayPause.rawValue)]
        self.view!.addGestureRecognizer(tapPlayPause)
    
         // menu
        let tapMenu = UITapGestureRecognizer()
        tapMenu.addTarget(self, action: "pressedTVRemoteMenuButton")
        tapMenu.allowedPressTypes = [NSNumber (integer: UIPressType.Menu.rawValue)]
        self.view!.addGestureRecognizer(tapMenu)
    
        // swipe right
        let rightSwipe = UISwipeGestureRecognizer(target: self, action: "swipedRightTVRemote")
        rightSwipe.direction = UISwipeGestureRecognizerDirection.Right
        self.view!.addGestureRecognizer(rightSwipe)
    
        // swipe left ...
        // swipe up ...
        // swipe down ...
    }
    
    
    func pressedTVRemoteSelectButton() {
         // do something
    }
    
    func pressedTVRemotePlayPauseButton() {
         // do something
    }
    
    func pressedTVRemoteMenuButton() {
         // do something
    }
    
    func swipedRightTVRemote() {
        // do something
    }
    

    You can do different methods for different scenarios. In my game I just converted to tvOS I have 1 like the example above and than 2 more like this in my GameScene.swift

    1) loadTVPauseControls() // new gestures for when game is paused

    2) loadTVGameOverControls() // new gestures for when game is game over

    Simply use the below method to disable the gestures before you change them or when you transition to a new scene.

    // MARK: - Disable All Gestures
    func disableAllGestures() {
        guard let view = view else { return }
        guard view.gestureRecognizers != nil else { return }
        for gesture in view.gestureRecognizers! {
            if let tapRecognizer = gesture as? UITapGestureRecognizer {
                view.removeGestureRecognizer(tapRecognizer)
            }
            if let swipeRecognizer = gesture as? UISwipeGestureRecognizer {
                view.removeGestureRecognizer(swipeRecognizer)
            }
        }
    }