0

我有一个在根目录下带有标签栏控制器的应用程序。“主视图”是 OpenGL 中的 3D 渲染屏幕。您可以单击某些需要显示视频的 3D 对象。视频应该是全屏并淡入淡出。

为此,我让 HomeViewController 创建了一个 MPMoviePlayerViewController,为其分配了一个 URL,然后从选项卡栏控制器呈现它。(我会从 HomeViewController 中展示它,但由于某种原因它没有正确改变它的方向——我确信它与所有自定义 3D 的东西有关,而且我没有对其进行编程,所以我只是做了一个通过从高级视图显示它来解决问题。)

(请注意,我以模态方式呈现 MPMoviePlayerViewController(不使用内置的 presentModalMovieViewController 或其他),因为 Apple 强制转换为古怪的屏幕移位,我想要溶解。)

现在,效果很好。模态窗口消失,视频播放。您可以播放和暂停它,快进,点击“完成”,模态窗口就会消失。瞧。

现在,出现了一个完全奇怪的错误:如果您不点击视频播放器并让控件淡出(就像它们在一两秒后所做的那样),用户无法通过点击将它们带回来。似乎视频控制器在淡出之后停止响应用户输入。同样,在它们消失之前它工作得很好。但在那之后,我必须等待视频播放完(实际上,模态窗口确实会消失)。

作为参考,这里是模态视频播放器的相关代码:

-(void) startVideoWithURL:(NSURL *)videoURL {

    if (!self.outsideMoviePlayerViewController) {
        self.outsideMoviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:nil];
    }

    if (videoURL) {

        [self stopAnimation];

        self.outsideMoviePlayerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        self.outsideMoviePlayerViewController.moviePlayer.contentURL = videoURL;

        [[[AppController instance] getCustomTabBarViewController] presentModalViewController:self.outsideMoviePlayerViewController animated:YES];

        // Move observation of the dismiss from the MoviePlayerViewController to self.
        [[NSNotificationCenter defaultCenter] removeObserver:self.outsideMoviePlayerViewController
                                                        name:MPMoviePlayerPlaybackDidFinishNotification
                                                      object:self.outsideMoviePlayerViewController.moviePlayer];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(movieFinishedCallback:)
                                                     name:MPMoviePlayerPlaybackDidFinishNotification
                                                   object:self.outsideMoviePlayerViewController.moviePlayer];

    }

}

-(void) movieFinishedCallback:(NSNotification *)aNotification {

    // Summary: Restart 3D animation, unregister from notifications, kill the modal video.

    [self startAnimation];

    MPMoviePlayerController *moviePlayer = [aNotification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:moviePlayer];

    [[[AppController instance] getCustomTabBarViewController] dismissModalViewControllerAnimated:YES];

}

对于此类问题,我能找到的唯一其他参考资料是 Apple 支持社区上的一些存档帖子,此处为:

https://discussions.apple.com/thread/2141156?start=0&tstart=0

在此线程中,问题发布者自己解决了问题,并声明问题已解决。这是他的解释:

CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) 时会出现问题。在我更改为 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, TRUE) 后,播放控件可以通过点击屏幕出现/消失。

不幸的是,我不是在编写游戏,我的开发团队中没有人在代码中的任何地方调用 CFRunLoopRunInMode。我发现最接近这一点的是动画代码(在同一个 ViewController 中):

- (void)startAnimation
{
    if (!animating)
    {
        NSLog(@"startAnimation called");
        CADisplayLink *aDisplayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
        [aDisplayLink setFrameInterval:animationFrameInterval];
        [aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.displayLink = aDisplayLink;

        animating = TRUE;
    }
}

如果有人对可能导致这种情况的原因有任何见解,我将不胜感激。我认为,至少,即使我今晚自己解决了这个问题,这个问题也可能会出现在 Stack Overflow 上并被存档以供后代使用。

干杯。

4

1 回答 1

0

我弄清楚是什么导致了这个问题。

我注意到第一个视频确实播放了,而后面的视频没有。我移动了这段代码:

if (!self.outsideMoviePlayerViewController) {
        self.outsideMoviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:nil];
}

这样,outsideMoviePlayerViewController 的创建就在下一个块内,如下所示:

if (videoURL) {

        self.outsideMoviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:nil];

        [self stopAnimation];

        self.outsideMoviePlayerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        self.outsideMoviePlayerViewController.moviePlayer.contentURL = videoURL;

现在,每次播放视频时都会创建一个新控制器,而不是回收控制器。虫子消失了。我不是 100% 确定为什么会发生这种情况,因为当您显示模态视图控制器时会发生各种各样的事情。

底线可能是我应该首先将其作为延迟加载范例的一部分,而不是试图将控制器保留在内存中。

于 2012-09-16T01:31:08.743 回答