在全屏MPMoviePlayerController上强制横向方向会导致退出全屏时旋转不正确。

14

我有一个iPhone应用程序(iOS6+),支持所有界面方向。但是,当MPMoviePlayerController以全屏方式播放视频时,只支持横向方向。

我在Stack Overflow上找到了以下解决方案,它有效。

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];

...

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    if (self.landscapeOnlyOrientation) {
        return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
    }
    return UIInterfaceOrientationMaskAll;
}

- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
    self.landscapeOnlyOrientation = YES;
}

- (void)moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
    self.landscapeOnlyOrientation = NO;
}
然而,一个烦人的问题仍然存在,即如果视频在强制横屏后退出全屏模式进入竖屏模式,则底层视图不会旋转回来。我必须手动将设备旋转到横向再旋转回竖向以触发方向更新。有没有办法通过编程来触发这种更新呢?
以下一组屏幕截图应说明我的意思:
NB:由于各种原因,不可能使用MPMoviePlayerViewController。

1
我几个月前向苹果提交了一个关于这个问题的错误报告。我建议你也这样做。问题在于底层视图控制器的方向方法没有被咨询。 - matt
有没有绕过的建议? - svth
不行。你可以尝试防止使用全屏模式。或者干脆不要使用MPMoviePlayerController。基本上这只是苹果的一个大混乱,开发人员需要继续向他们施压,直到他们解决这个问题。 - matt
你有检查过这个答案吗?它附带了一个示例项目,可能会对你有所帮助。https://dev59.com/RGUo5IYBdhLWcg3wkAHB#16022631 - Adrian P
8个回答

11

大家好,我遇到了同样的问题,我已经解决了 -

这是我的完整代码...

你需要首先在appdelegate中做出更改:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([[[NowPlaying sharedManager] playerViewController] allowRotation])//Place your condition here
{
    return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}

为全屏控制注册通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillEnterFullscreenNotification:)
                                             name:MPMoviePlayerWillEnterFullscreenNotification
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerWillExitFullscreenNotification:)
                                             name:MPMoviePlayerWillExitFullscreenNotification
                                           object:nil];

然后在玩家控制器中添加以下代码行:

- (void)moviePlayerWillEnterFullscreenNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^
               {
                   self.allowRotation = YES;
               });
}



- (void)moviePlayerWillExitFullscreenNotification:(NSNotification *)notification
{
self.allowRotation = NO;
[self.moviePlayerController setControlStyle:MPMovieControlStyleNone];

dispatch_async(dispatch_get_main_queue(), ^
               {

                   //Managing GUI in pause condition
                       if (self.currentContent.contentType == TypeVideo && self.moviePlayerController.playbackState == MPMoviePlaybackStatePaused)
                   {
                       [self.moviePlayerController pause];
                       if (self.playButton.selected)
                           self.playButton.selected = NO;
                   }
                   self.view.transform = CGAffineTransformMakeRotation(0);
                   [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
                   self.view.bounds = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
               });
}

这段代码在iOS6和iOS7中测试都能正常工作。谢谢 :)

如果有任何问题,请告诉我.....


我需要检查什么条件?如果([[[NowPlaying sharedManager] playerViewController] allowRotation])//在这里放置您的条件。那么“NowPlaying”是什么意思? - karthikeyan
嗨,Vijay,感谢提供代码。在WillExitFullScreen方法中删除dispatch_async代码后,它可以正常工作。您能否简要地解释一下为什么要放置无用的代码以及什么是TypeVideo? - Satya
1
感谢Satya的评论。我使用dispatch_async来访问主线程,因为在我的情况下,当我进入横向模式时,我的先前的GUI在动画过程中会变形。在我的情况下,我正在同一个播放器上播放音频和视频,并且每当视频开始播放时,它会全屏显示,而不是在音频歌曲中。因此,我使用TypeVideo来为视频歌曲分类。 - Vijay Sharma
抱歉karthikeyan,回复晚了。在我的情况下,当我进入全屏播放器模式时,PlayerViewController会变成横向。因此,在播放器视图控制器上调用“-(void)moviePlayerWillEnterFullscreenNotification”通知方法时,我会说是的,现在允许所有旋转,“self.allowRotation = YES;”如果您对此不清楚,请告诉我。 谢谢。 - Vijay Sharma

5

您需要创建子类并将横屏设置为支持的界面方向。

@interface MyMovieViewController : MPMoviePlayerViewController
@end

@implementation MyMovieViewController

- (BOOL)shouldAutorotate 
{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations 
{
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}

@end

2
你可以尝试“强制”刷新方向,让系统为您处理正确的方向:
- (void)forceOrientationRefresh
{
    // Force orientation refresh
    [self presentModalViewController:[UIViewController new]
                            animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

这个方法虽然有些取巧,但是确实有效。


1
你可以通过编程来改变你的方向,像这样:

-(void)viewDidAppear:(BOOL)animated
{

     if(UIDeviceOrientationIsPortrait(self.interfaceOrientation)){
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
        {
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft );

        }
    }

}

别忘了添加 #import <objc/message.h>

0

您可以使用supportedIterfaceOrientationsForWindow,然后查找:MPInlineVideoFullscreenViewController。找到正确的视图控制器有点棘手,但它能够正常工作。

以下是示例代码:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    if ([NSStringFromClass([self.window.rootViewController.presentedViewController.presentedViewController class]) isEqualToString:@"MPInlineVideoFullscreenViewController"]){
    return UIInterfaceOrientationMaskAllButUpsideDown;
}
    return UIInterfaceOrientationMaskLandscape;
}

0

我认为你可以为设备方向注册你的视图控制器并强制调用视图控制器的方向方法。


0
这可能听起来有些疯狂,但是你可以在打开视频视图控制器之前尝试本地保存最后的方向,然后使用 application:supportedInterfaceOrientationsForWindow: 返回保存的方向并强制视图控制器保持在该方向上而不进行旋转。

-1

你需要为iOS7添加这段代码,它非常完美和简单。

-(NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

.... creating a player
MPMoviePlayerViewController *mp =[[MPMoviePlayerViewController alloc] initWithContentURL:url];
...make settings and present it
[self presentMoviePlayerViewControllerAnimated:mp];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接