如何在MPMoviePlayerController电影播放之前隐藏控件?

20

假设iOS版本为3.2或更高。播放电影时,如何按正确顺序执行命令以播放一个控件最初被隐藏的移动画面。当用户正在观看电影时,可以选择在屏幕上打标签并显示控件。

谢谢!

我(控件不隐藏)的代码:

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

    // Register to receive a notification when the movie has finished playing.  
    [[NSNotificationCenter defaultCenter] addObserver:self  
                                             selector:@selector(movieDone:)  
                                                 name:MPMoviePlayerPlaybackDidFinishNotification  
                                               object:moviePlayer];  

    [[NSNotificationCenter defaultCenter] addObserver:self  
                                             selector:@selector(movieState:)  
                                                 name:MPMoviePlayerNowPlayingMovieDidChangeNotification  
                                               object:moviePlayer];  

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(movieReady:) 
                                                 name:MPMoviePlayerLoadStateDidChangeNotification 
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullScreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullScreen:) name:MPMoviePlayerWillExitFullscreenNotification object:moviePlayer];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishPlayback:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];


    if ([moviePlayer respondsToSelector:@selector(setFullscreen:animated:)]) {  
        moviePlayer.controlStyle = MPMovieControlStyleDefault; // MPMovieControlStyleNone MPMovieControlStyleEmbedded MPMovieControlStyleFullscreen MPMovieControlStyleDefault
        moviePlayer.scalingMode = MPMovieScalingModeAspectFill; // MPMovieScalingModeAspectFit MPMovieScalingModeAspectFill
    }   
}

- (void) movieReady:(NSNotification*)notification 
{
    MPMoviePlayerController *moviePlayer = [notification object];  

    if ([moviePlayer loadState] != MPMovieLoadStateUnknown) {
        // Remove observer
        [[NSNotificationCenter defaultCenter] removeObserver:self  
                                                        name:MPMoviePlayerLoadStateDidChangeNotification  
                                                      object:nil];

        // When tapping movie, status bar will appear, it shows up
        // in portrait mode by default. Set orientation to landscape
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO];
        [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

        // Add movie player as subview
        [[self view] addSubview:[moviePlayer view]];   

        // Play the movie
        [moviePlayer play];
        [moviePlayer setFullscreen:YES animated:YES];       
    }
}
3个回答

35
[更新] 正如 @ReinYem 提出的建议,一个更好的解决方案是依靠MPMoviePlayerLoadStateDidChangeNotification而不是定时器。 实际上,以下解决方案不再被考虑:
controlStyle 属性设置为 MPMovieControlStyleNone ,然后使用 [performSelector:withObject:afterDelay:1] 在一秒钟后将其设置为 MPMovieControlStyleFullscreen 。 它可以很好地工作,控件在用户点击视频之前不会出现。

1
不错的提示。我也发现,如果在调用播放后立即将控件样式设置为MPMovieControlStyleFullscreen,它会达到相同的效果。所以也许没有必要指定一个任意的1秒延迟? - curthipster
一个一秒的延迟对我也起作用了。我尝试了半秒钟,但那太快了。 - Tod Cunningham
是的,我也需要一个延迟,但仍在想为什么需要引入这样的延迟。 - VARUN ISAC

34

使用回调函数而不是定时器:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hidecontrol) 
                                                 name:MPMoviePlayerLoadStateDidChangeNotification 
                                               object:playerView.moviePlayer];

使用回调函数:

- (void) hidecontrol {
[[NSNotificationCenter defaultCenter] removeObserver:self     name:MPMoviePlayerNowPlayingMovieDidChangeNotification object:playerView.moviePlayer];
[playerView.moviePlayer setControlStyle:MPMovieControlStyleFullscreen];

}

我非常喜欢这个解决方案,因为它比定时器更精确地覆盖了所需的行为,完全消除了播放但然后暂停或隐藏的竞争条件(假设在这些情况下您也清理了此观察者)。 - Rob Rix
这不仅是“更好”的解决方案,而且它是正确的解决方案。另一个在面对不可预测的竞争条件时会失败。 - kevlar
3
不确定这在iOS 6上是否仍有效。似乎加载状态loadState是否过早改变是随机的。观察MPMoviePlayerPlaybackStateDidChangeNotification通知中playbackState是否改变为MPMoviePlaybackStatePlaying似乎更加可靠。 - David Snabel-Caunt
1
@DavidCaunt:你的解决方案已经不再适用了。在iOS 7上,设置电影控件会立即显示它们。 - Ricardo Sanchez-Saez
2
你能解释一下为什么要移除 MPMoviePlayerNowPlayingMovieDidChangeNotification 的观察者吗? - eyuelt

10
player.moviePlayer.controlStyle = MPMovieControlStyleNone;

是最新的做法。:)


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