1

I have a tvOS app, with a UITabBarController as the main entry point for the main storyboard. If the user is not logged in, the UITabBarController presents a LoginViewController modally.

When the user presses the Menu button on the Siri remote, the system automatically dismiss the LoginViewController and shows the UITabBarController. I want the app to instead exit to the tvOS headboard.

Expect the solution to involve either a UITapGestureRecognizer to override the Menu button action, or overriding pressesBegan/pressesTouched, but I haven't found a solution yet.

Ric Santos
  • 15,419
  • 6
  • 50
  • 75

2 Answers2

5

This following snippet works, and is acceptable behavior based on the expected behavior for a menu button in Apples HIG for Remotes and Interactions

override func viewDidLoad() {
    super.viewDidLoad()

    let tapRecognizer = UITapGestureRecognizer(target: self, action: "tapped")
    tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.rawValue)];
    self.view.addGestureRecognizer(tapRecognizer)
}

func tapped() {
    exit(EXIT_SUCCESS)
}
Campbell_Souped
  • 871
  • 10
  • 22
  • 1
    Although this 'works', it is discouraged by Apple to exit programatically https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/StartingStopping.html – Ric Santos Jan 03 '16 at 22:44
  • 1
    @RicSantos keep in mind the link you provided is about iOS, not tvOS. If you take a look at the [Remote and Interactions HIG](https://developer.apple.com/tvos/human-interface-guidelines/remote-and-interaction/), for tvOS, you will notice that the expected behavior in an app for the menu button is "Returns to previous screen." AND "Exits to Apple TV Home screen." – Campbell_Souped Jan 10 '16 at 23:08
  • Here's the correct Remote HIG page: https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ – Justin Vallely Nov 12 '16 at 17:33
  • `exit(EXIT_SUCCESS)` works with Xcode9.1, tvOS 11.1 on Apple TV 4K simulator. – Nao Ohta Dec 01 '17 at 05:47
3

I had a very similar situation, it looked like this:

               +--------------------+
        ------>| MainViewController |
               +--------------------+
                         |
           +-------------+-------------+
           |                           |
           v                           v
+---------------------+      +--------------------+
| LoginViewController |      | HomeViewController |
+---------------------+      +--------------------+

If either LoginViewController or HomeViewController are presented then I want the menu button to dismiss the app and return to the TV home screen, not to MainViewController.

After much Googling, I settled upon this solution and it seems to work well without triggering warnings or requiring a call to exit.

class MainViewController: UIViewController {
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)
        UIApplication.shared.keyWindow?.rootViewController = segue.destination
    }
}

Hope this is helpful to somebody out there

Jamie White
  • 341
  • 1
  • 5