navigationBar 和 MPMoviePlayerController 的极其奇怪的行为。 iOS中的错误或我的错误?

Posted

技术标签:

【中文标题】navigationBar 和 MPMoviePlayerController 的极其奇怪的行为。 iOS中的错误或我的错误?【英文标题】:Extremely weird behavior of navigationBar and MPMoviePlayerController. Bug in iOS or my error? 【发布时间】:2011-12-02 05:13:56 【问题描述】:

我有一个MPMoviePlayerController 对象,它可以纵向或横向全屏播放视频。如果我在视频播放时旋转方向并在视频开始播放并且视频状态栏可见后几秒钟内进行旋转,那么当视频结束时,我的导航栏是完美的。但是,如果我等到视频状态栏在视频播放几秒钟后消失,然后旋转方向,当视频结束时,我的 navigationBar 部分隐藏在状态栏后面,就像向上推一样。

你见过这样的事情吗?

我能够轻松地重新创建此错误。我创建了一个新的单一视图应用程序,并简单地添加了一个按钮和一个导航栏。如果我在播放视频时旋转方向,点击以启用全屏并且视频状态栏仍然可见,当视频播放完毕时,一切都很好。但是,如果我在视频状态栏消失后等待旋转,当我旋转视频结束时,导航栏位于状态栏下方。见图片:

iPhone Image

这是我正在使用的简单代码:

- (void) playMovie 
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource: @"movie" ofType: @"mov"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: url];

[[NSNotificationCenter defaultCenter] addObserver: self 
                                         selector: @selector(moviePlayBackDidFinish:) 
                                             name: MPMoviePlayerPlaybackDidFinishNotification 
                                           object: moviePlayer];

moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;

[self.view addSubview: moviePlayer.view];
[moviePlayer setFullscreen: YES animated: YES];

- (void) moviePlayBackDidFinish: (NSNotification *) notification
    MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver: self 
                                                name: MPMoviePlayerPlaybackDidFinishNotification 
                                              object: player];

if ([player respondsToSelector: @selector(setFullscreen:animated:)])

    [player.view removeFromSuperview];

以下是我目前的建议。我一定有什么问题,因为不幸的是我仍然有同样的问题。

这里是方法onPlayerWillExitFullScreen

UIView *view = [[[UIApplication sharedApplication] delegate].window.subviews lastObject];    
if (view) 
    [view removeFromSuperview];
    [[[UIApplication sharedApplication] delegate].window addSubview:view]; 


MPMoviePlayerController *player = [aNotification object];
[[NSNotificationCenter defaultCenter] removeObserver: self 
                                                name: MPMoviePlayerWillExitFullscreenNotification 
                                              object: player];    

这是我目前的playMovie 方法:

 NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource: @"movie" ofType: @"mov"]];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL: url];

[[NSNotificationCenter defaultCenter] addObserver: self 
                                         selector: @selector(moviePlayBackDidFinish:) 
                                             name: MPMoviePlayerPlaybackDidFinishNotification 
                                           object: moviePlayer];

[[NSNotificationCenter defaultCenter]addObserver: self
                                        selector: @selector(onPlayerWillExitFullScreen:) 
                                            name: MPMoviePlayerWillExitFullscreenNotification 
                                          object: self.moviePlayer];

moviePlayer.controlStyle = MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay = YES;

[self.view addSubview: moviePlayer.view];
[moviePlayer setFullscreen: YES animated: YES];

【问题讨论】:

您可能需要包含一两个屏幕截图。 您的屏幕截图链接已损坏。 【参考方案1】:

好的,所以我首先在 UIWebView 然后在 MPMoviePlayerController 中在我的应用程序中发现了这个可怕的相同错误,我解决了这个问题,将此代码放置在我的视图控制器中。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
    [self.navigationController setNavigationBarHidden:YES animated:YES];
    [self.navigationController setNavigationBarHidden:NO animated:YES];

棘手的错误,棘手的修复。

【讨论】:

终于!!非常感谢。我不得不玩一点,但让它发挥作用。我把代码放在我的 -(void) movieFinished: (NSNotification *) aNotification【参考方案2】:

如果您侦听 MPMoviePlayerWillExitFullscreenNotification 通知,您可以强制主视图正确重绘,如下所示。引用的“窗口”是应用程序的主 UIWindow 对象。

当 MPMoviePlayerController 切换到全屏时,它实际上创建了一个单独的 UIWindow 实例来呈现视频。通过在通知转换回来时捕获通知,此代码将确保您切换回的视图正确重新对齐。

诚然,这不是一个优雅的解决方案,但它每次都有效。

UIView *view = [window.subviews lastObject];
if (view) 
     [view removeFromSuperview];
     [window addSubview:view];

要收听此通知,您需要执行以下操作,其中 self.playerController 是您的 MPMoviePlayerController 对象。

但请记住,一旦您释放播放器,就停止收听此通知!

    // Determine the default notification centre
    NSNotificationCenter *centre = [NSNotificationCenter defaultCenter];
    // Listen for interesting movie player notifications
    [centre addObserver: self
               selector: @selector(onPlayerWillExitFullScreen:) 
                   name: MPMoviePlayerWillExitFullscreenNotification 
                 object: self.playerController];

【讨论】:

感谢您的帮助。我是编程新手,所以我不太确定如何实现该通知,但我会试一试。知道有解决方案,我感到非常欣慰。 更新了我的答案,为你包括了这个。 我对 UIWindow 对象感到困惑。以我的简单测试应用程序为例,我所拥有的只是一个只有一个按钮和一个导航栏的单一视图应用程序。我试图用“self.view”子“窗口”,但一定不正确。 在您的应用程序委托中,您将拥有对 UIWindow 对象的引用——这就是您想要的。 感谢您的耐心等待!在我的应用程序委托文件中,它指的是 UIWindow *window,它被合成为 window = _window。 window 和 _window 都给我一个未声明的标识符错误。【参考方案3】:
- (void) moviePlayerWillExitFullScreen:(id)sender 

[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:NO];


伙计们试试这个...它对我有用。我尝试了许多其他方法,只有这一种有效。

【讨论】:

以上是关于navigationBar 和 MPMoviePlayerController 的极其奇怪的行为。 iOS中的错误或我的错误?的主要内容,如果未能解决你的问题,请参考以下文章

iOS navigationBar和tabBar变透明 & navigationBar根据滑动距离的渐变色实现

UIPrintInteractionController 和 UIAppearance 的 navigationBar

NavigationBar 和导航按钮中的单独标题

SearchBar 和 NavigationBar 之间的空格 - Swift

Android之SystemUI载入流程和NavigationBar的分析

为啥navigationBar和view之间显示黑屏