Swick
Swick

Reputation: 177

xcode tvos app exiting issue when overriding menu button

I am currently writing a tvOS app. I've been detecting and overriding the menu button with tapRecognizer to switch between storyboards and other functions. My issue is when I am on my home screen and press menu it does not exit the app. Instead it remembers the last function I used when overriding the menu button and performs that function. Any thoughts on how to clear the tapRecognizer? Or a function that will exit the app?

I'm overriding the menu button with

in Storyboard1

tapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(home)];
tapRecognizer.allowedPressTypes = @[[NSNumber numberWithInteger:UIPressTypeMenu]];
[self.view addGestureRecognizer:tapRecognizer];

in my home subroutine I send the user back to my home page storyboard. But from then on the menu button will not exit the app but send me back to storyboard1. thanks, SW

Upvotes: 11

Views: 9720

Answers (7)

Abhishek Thapliyal
Abhishek Thapliyal

Reputation: 3708

SwiftUI Seekers:

I don't know how much this answer helps, but just adding available actions in SwiftUI.

YourAnyView
  .onExitCommand(perform: {
      print("onExitCommand")
  })
  .onMoveCommand { direction in
      print("onMoveCommand", direction)
  }

REF:

onmovecommand

onexitcommand

Upvotes: 0

atulkhatri
atulkhatri

Reputation: 11343

As per Apple's documentation, for custom press handling, we should override all four of these methods-

- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event NS_AVAILABLE_IOS(9_0);

This is the official documentation from XCode:

Generally, all responders which do custom press handling should override all four of these methods.

Your responder will receive either pressesEnded:withEvent or pressesCancelled:withEvent: for each

press it is handling (those presses it received in pressesBegan:withEvent:).

pressesChanged:withEvent: will be invoked for presses that provide an analog value (like thumbsticks or analog push buttons)

*** You must handle cancelled presses to ensure correct behavior in your application. Failure to do so is very likely to lead to incorrect behavior or crashes.

Upvotes: 0

Sankalap Yaduraj Singh
Sankalap Yaduraj Singh

Reputation: 1199

It may be help you... it is swift code.

let menuPressRecognizer = UITapGestureRecognizer()
menuPressRecognizer.addTarget(self, action: #selector(YourViewController.menuButtonAction(_:)))
menuPressRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.Menu.hashValue)]
self.view.addGestureRecognizer(menuPressRecognizer)

Upvotes: 0

matthiaswitt
matthiaswitt

Reputation: 196

If you overwrite the menu button, the app won't be accepted:

EDIT: You can overwrite, but the menu button has to work as a back button to homescreen from the entry point of the app.

10.1 Details

The Menu button on the Siri Remote does not behave as expected in your app.

Specifically, when the user launches the app and taps the Menu button on the Siri remote, the app does not exit to the Apple TV Home screen.

Next Steps

Please revise your app to ensure that the Siri remote buttons behave as expected and comply with the Apple TV Human Interface Guidelines.

Upvotes: 2

skywinder
skywinder

Reputation: 21436

You have to override 2 methods to prevent exiting app by pressing Menu button.

Here is ready-to-use template:

override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
    for press in presses {
        switch press.type {
        case .Menu:
            break
        default:
            super.pressesBegan(presses, withEvent: event)
        }
    }
}

override func pressesEnded(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
    for press in presses {
        switch press.type {
        case .Menu:
            //Do some staff there!
            self.menuButtonPressed()
        default:
            super.pressesEnded(presses, withEvent: event)
        }
    }
}

Upvotes: 5

sven7
sven7

Reputation: 748

If you are using UIGestureRecognizer instead of responding to presses, all you need to do is to disable the recognizer:

tapRecognizer.enabled = NO;

So if no recognizer with UIPressTypeMenu is listening, tvOS suspends the app and displays the home screen. (I've tested this)

Upvotes: 4

ehynds
ehynds

Reputation: 4463

Instead of using your own gesture recognizer, override pressesBegan:

override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
  if(presses.first?.type == UIPressType.Menu) {
    // handle event
  } else {
    // perform default action (in your case, exit)
    super.pressesBegan(presses, withEvent: event)
  }
}

Upvotes: 16

Related Questions