当远程按下菜单按钮时,Apple TV App不会从初始视图控制器退出到主屏幕

时间:2022-07-14 00:03:57

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

我刚刚因为Apple电视应用被拒绝了

'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.'

'此外,Siri Remote上的菜单按钮在您的应用程序中的行为与预期不符。具体来说,当用户启动应用程序并点击Siri遥控器上的菜单按钮时,该应用程序不会退出Apple TV主屏幕。

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.

我想我可以截取菜单按钮并按下exit(0),但这似乎不是一种优雅的退出方式。

6 个解决方案

#1


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.

我也因为这个原因拒绝了应用程序。在我的情况下,问题是覆盖了按 d:withEvent方法组,而没有调用超级实现。

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.

菜单按钮再次起作用。令人困惑的是,无论你是否打电话,主页按钮都会继续工作。

#2


2  

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

我在tvOS 9.1中的完整工作代码(在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];
}

#3


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.

如果你在屏幕上显示某些东西,比如一个不受标准sdk控制的弹出框/对话框,而是你自己手工制作(即添加一个UIView作为弹出框),那么Menu按钮应该像'取消/返回'一样它会在导航控制器上做。

-(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
}

#4


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;
    }
}

#5


0  

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

所以我最终不情愿地调用exit(0)

- (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.

它不像它自动工作那样整洁;你最终得到一个模糊的白色视图大约半秒钟而不是更优雅的淡出动画。然而它确实有效,我可以确认我是通过Apple的审查流程这样做的。

#6


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.

这样,菜单按钮的工作方式应该是这样,您无需调用exit()或强制您的应用程序以其他方式退出。

#1


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.

我也因为这个原因拒绝了应用程序。在我的情况下,问题是覆盖了按 d:withEvent方法组,而没有调用超级实现。

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.

菜单按钮再次起作用。令人困惑的是,无论你是否打电话,主页按钮都会继续工作。

#2


2  

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

我在tvOS 9.1中的完整工作代码(在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];
}

#3


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.

如果你在屏幕上显示某些东西,比如一个不受标准sdk控制的弹出框/对话框,而是你自己手工制作(即添加一个UIView作为弹出框),那么Menu按钮应该像'取消/返回'一样它会在导航控制器上做。

-(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
}

#4


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;
    }
}

#5


0  

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

所以我最终不情愿地调用exit(0)

- (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.

它不像它自动工作那样整洁;你最终得到一个模糊的白色视图大约半秒钟而不是更优雅的淡出动画。然而它确实有效,我可以确认我是通过Apple的审查流程这样做的。

#6


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.

这样,菜单按钮的工作方式应该是这样,您无需调用exit()或强制您的应用程序以其他方式退出。