Apple TV App not exiting to the home screen from initial view controller when menu button pressed on remote
Asked Answered
B

6

10

I've just had an Apple TV app rejected because of

'In addition, 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.'

I'm looking this up and from what I can tell this should be the automatic behaviour of pressing the menu button when on the initial view controller. However I have a navigation controller with a root view controller, instantiated automatically via the storyboard with no methods overridden and nothing happens when I press the menu button on this view controller.

Can someone tell me if I'm missing something or if there's a way of implementing this manually?

I'm thinking I could just intercept the menu button press and call exit(0), but that doesn't seem like a graceful way of exiting.

Butyl answered 23/10, 2015 at 12:14 Comment(3)
If you're seeing this behavior in, say, an empty app with just the storyboard setup you describe, you may have found a bug. (If not, start working piecewise to see how your app differs.) File that bug.Cointon
Yeah I'm pretty sure it's a bug. I'm going to file a bug report. If I create a brand new view controller, with nothing on it, it works. If I add a few labels, buttons, image views and custom fonts (even without hooking anything up or using my own subclasses) it suddenly stops.Butyl
Example of how to return to the Apple TV home screen manually in Swift: Allow Siri Remote Menu button when Play/Pause button is overridden.Bodhisattva
W
5

I just had an app rejected for this reason too. In my case the problem was overriding the press<Phase>d:withEvent group of methods without calling the super implementation.

So I changed this:

-(void)pressesBegan:(NSSet*)presses withEvent:(UIPressesEvent *)event {
    // my code
}

To this:

-(BOOL)ignoreMenu:(NSSet*)presses {
    return ((UIPress *)[presses anyObject]).type == UIPressTypeMenu;
}

-(void)pressesBegan:(NSSet*)presses withEvent:(UIPressesEvent *)event {
    if ([self ignoreMenu:presses]) return [super pressesBegan:presses withEvent:event];
    // my code
}

And the menu button works again. What's confusing is that the Home button continues to work whether you call the super or not.

Winfordwinfred answered 24/10, 2015 at 20:59 Comment(1)
Don't forget to make a similar call to -ignoreMenu: from -pressesEnded: if you're overriding that too.Sipe
M
2

My complete working code as of tvOS 9.1 (compiled under Objective-C++)

bool AppRespondedToBack = false;
-(void)pressesBegan:(NSSet*)presses withEvent:(UIPressesEvent *)event
{
    UIPress *UP = (UIPress *)presses.anyObject;
    if ( UP && UP.type == UIPressTypeMenu )
    {
        //OnBack should be where you handle the back operation in your app
        AppRespondedToBack = OnBack();
        if ( !AppRespondedToBack )
            // Let AppleTV return to the home screen
            [super pressesBegan:presses withEvent:event];
    }
    else
        [super pressesBegan:presses withEvent:event];
}
-(void)pressesEnded:(NSSet*)presses withEvent:(UIPressesEvent *)event
{
    UIPress *UP = (UIPress *)presses.anyObject;
    if ( UP && UP.type == UIPressTypeMenu )
    {
        if ( !AppRespondedToBack )
             // Let AppleTV return to the home screen
            [super pressesEnded:presses withEvent:event];
    }
    else
        [super pressesEnded:presses withEvent:event];
}
Merrileemerrili answered 15/12, 2015 at 18:10 Comment(1)
BTW, controllerUserInteractionEnabled also needs to be set to YES (for Objective C) or true (for Swift), at the ViewController level, else passing the presses events to super, for the menu key has no effect.Luhe
D
1

In a more generic way, the Menu button should take you to the home screen only in some conditions, first one would be when you start the app and click the Menu button, and later on in your app if you are at the 'root view' of your app.

If you display something on the screen, like a popover/dialog which is not controlled by the standard sdk but manualyl by yourself (ie adding a UIView as popover), then the Menu button should just act as a 'cancel/go back' like it would do on the navigation controller.

-(void)pressesBegan/Ended:(NSSet*)presses withEvent:(UIPressesEvent *)event {
    if( presses.anyObject.type == UIPressTypeMenu) {
        if ( !somePopoverDisplayed) {
                // Let the sdk do its thing with the menu button 
            [super pressesBegan:presses withEvent:event];
        } else {
            // otherwise handle the menu button yourself ...
        }
        return;
    }

    // handle other buttons
}
Dib answered 4/11, 2015 at 4:13 Comment(1)
This is the one that worked for me, with a minor difference. For whatever reason, calling the [super pressesBegan...] method made it so the app didn't return to the apple tv menuExplanatory
E
1

Here is the snipped of code that ended up working for me:

-(void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
    if( presses.anyObject.type == UIPressTypeMenu) {
        if (scene.view.paused == YES) {
            // This will return to the Apple TV Menu           
        } else {
            // This allows your code to run without exiting the app
            [self pauseScene];
            [super pressesBegan:presses withEvent:event];
        }
        return;
    }
}
Explanatory answered 8/11, 2015 at 20:50 Comment(0)
B
0

So I ended up begrudgingly calling exit(0) like so

- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
    [super pressesBegan:presses withEvent:event];

    if (presses.anyObject.type == UIPressTypeMenu)
    {
        exit(0);
    }
}

It's not quite as neat as when it works automatically; you end up with a blurry white view for about half a second instead of the more graceful fade out animation. It does however work and I can confirm that I made it through Apple's review process doing it this way.

Butyl answered 28/10, 2015 at 13:47 Comment(1)
Then you were lucky. Last time I made an exit() call, it was rejected. Apple said you mustn't call exit in apps.Obnubilate
T
0

What sorted it out for me was just removing the gesture recogniser from your view (for your Menu button) when you don't need it anymore.

Then when, you have a situation where you want the Menu button to for example, go back to a previous screen, then just add your gesture recogniser again.

That way the Menu button works the way it should, without you having to call exit() or force your app to quit some other way.

Teena answered 3/12, 2015 at 21:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.