gpt4 book ai didi

iphone - MPMoviewPlayerController 全屏播放旋转与底层 UIViewController 仅具有纵向模式(不允许旋转)

转载 作者:行者123 更新时间:2023-12-03 18:27:13 26 4
gpt4 key购买 nike

你好,

我有一个简单的应用程序,其中包含 UITabBarController 和两个 UIViewController。两个 UIViewController 都是纵向的(不允许旋转)。一个 UIViewController 的 UIView 确实包含 MPMoviePlayerController 的 View ,以允许在该 View 内播放视频,并且可以通过控件 (MPMovieControlStyleEmbedded) 使其全屏显示。代码很简单,看起来确实像......

__moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"MOVIE_URL"]];
__moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
__moviePlayer.view.frame = CGRectMake( 10, 10, 300, 200 );
__moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
__moviePlayer.shouldAutoplay = NO;
[__moviePlayer prepareToPlay];
[self.view addSubview:__moviePlayer.view];

...除非用户切换到全屏播放(我想允许旋转以允许横向播放),否则这确实可以完美工作。旋转不起作用,因为 UITabBarController 不允许旋转(两个 UIViewController 也是如此)。

因此,我尝试了两种方法,但都没有达到预期效果。

1) 子类化 UITabBarController

我确实添加了属性 BOOL __allowRotation,如果它设置为 YES,我会在 UITabBarController 的 shouldAutorotateToInterfaceOrientation 方法中返回 YES。

我正在监听 MPMoviePlayerDidEnterFullscreenNotification 和 MPMoviePlayerWillExitFullscreenNotification 通知,以将此属性设置为 YES 和 NO。

它确实有效,但问题是,当用户以横向方式结束视频播放时,底层 View 不会旋转回纵向。旋转回纵向的唯一方法是使用私有(private) API,这是不行的。

2) View /图层转换

我也尝试监听 MPMoviePlayerDidEnterFullscreenNotification 和 MPMoviePlayerWillExitFullscreenNotification 通知。

当我收到 MPMoviePlayerDidEnterFullscreenNotification 时,我将启动 UIDevice 方向通知以获取设备方向。我试图根据当前设备方向转换 MPMoviePlayerController 的 View 层,但它有点免疫,因为它什么也不做。我可以为转换属性分配任何内容,但它什么也不做。

它什么也没做并不完全正确。当我在旋转期间应用变换时,当我从全屏切换回嵌入式视频播放时,我可以看到此变换的效果。

3) 单独的 UIWindow

我还没有对此进行测试,但我发现 MPMoviePlayerController 为全屏播放创建了单独的 UIWindow,应该可以通过 [[UIApplication sharedApplication] windows] 访问它。这确实解释了为什么在全屏播放期间不应用转换。

但我非常不喜欢这个解决方案,因为 UIWindow 无法被识别,并且我不想使用像 objectAtIndex:1 这样的魔术常量或将转换应用于除主窗口之外的所有 UIWindows 等。

除此之外,底层实现可以修改并且它将停止工作。

问题

那么,问题是,当底层 UIView(即 UIView 的 UIViewController)禁止旋转而只允许纵向时,如何允许 MPMoviePlayerController 全屏播放只旋转?

最佳答案

我也有类似的情况。我的应用程序仅限纵向。但我需要以任何方向显示全屏视频,然后在用户退出全屏模式后返回到纵向方向。

Split 的方法对我来说不起作用,因为我想让用户以全屏和嵌入的方式观看视频,并在模式之间切换,而不丢失播放位置,并且没有任何暂停。

我找到了这个解决方法:

首先,我有一个根 UINavigationController 子类,它接收有关旋转的所有消息。

我禁止此 Controller 中的旋转:

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

我正在覆盖

- (id) initWithRootViewController:(UIViewController *)rootViewController; method. 

添加对设备方向修改的支持:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(receivedRotate:) name: UIDeviceOrientationDidChangeNotification object: nil];

现在我有一个处理程序receedRotate: - 尽管不会自动旋转到除纵向之外的任何方向,但它会捕获所有设备旋转:

- (void) receivedRotate:(NSNotification*) notify {
if(isVideoFullscreen) {
UIDeviceOrientation toInterfaceOrientation = [[UIDevice currentDevice] orientation];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
[UIView setAnimationCurve:2];

if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft){
self.view.transform = CGAffineTransformMakeRotation(-M_PI_2);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
self.view.bounds = CGRectMake(0, 0, 1024, 768);
} else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
self.view.transform = CGAffineTransformMakeRotation(M_PI_2);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
self.view.bounds = CGRectMake(0, 0, 1024, 768);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
self.view.transform = CGAffineTransformMakeRotation(M_PI);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortraitUpsideDown];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortrait) {
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
}

[UIView commitAnimations];
}

}

我只是检查设备的旋转,并相应地旋转我的 View 。

那么 - 根 Controller 如何知道视频何时全屏?只需将另外两个消息处理程序添加到 init 中即可:

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

以及处理程序本身:

- (void) willEnterFullscreen: (NSNotification *) notify {
isVideoFullscreen = YES;
}

- (void) willExitFullscreen: (NSNotification *) notify {
self.view.transform = CGAffineTransformMakeRotation(0);
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
self.view.bounds = CGRectMake(0, 0, 768, 1024);
isVideoFullscreen = NO;
}

退出全屏时 - 我们恢复纵向。所以,这对我有用,希望对某人有帮助。

关于iphone - MPMoviewPlayerController 全屏播放旋转与底层 UIViewController 仅具有纵向模式(不允许旋转),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5014176/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com