iOS屏幕旋转之为横屏视频播放增加竖屏模式
2014-11-16 22:08
1546 查看
在App Store上的大部分视频播放App中,都实现了竖屏小屏播放以显示更多相关信息,横屏切换到全屏播放,这样的交互显得优雅而大方。最近项目里有个这样的需求,为全屏视频播放加上竖屏模式。下面,让我们一起来实现这个需求。
强制更改设备方向,但该方法已经在iOS6中废止。另外一种更改设备方向的方法是通过重力感应触发。
那么视图方向是又什么决定的呢?
全局Info.plist
iOS6+在UIApplicationDelegate中增加了 - (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window;回调
UIViewController。并且只在UIWindow的rootViewController或model状态下的UIViewController有效
最终的视图方向取决于 (全局控制 ∩ UIWindow 中的回调 ∩ 单个界面控制) 的交集,如果交集为空,iOS6下抛出 UIApplicationInvalidInterfaceOrientationException 异常后崩溃。
横屏:
两张横竖屏的图片中,菜单、标题大小都发生了改变。下面我们就来讨论下实现的方法。
考虑到原来的视频播放器只支持横屏播放,这里采用的方案如下:竖屏状态下,先present一个只支持横屏的UIViewController,再将视频播放器作为横屏UIViewController的子控制器添加进来。这样可以触发iOS进行横竖屏检测。
当竖屏切到横屏时,旋转的动画设置。代码如下:
横屏切换到竖屏的动画实现如下:
以上是手动旋转过程。还有一种方法是直接旋转portraitViewController.view。人为旋转过程中,设备的原点并未发生改变,这需要考虑横竖屏布局问题。
iOS中的方向
iOS设备中有两种方向,一种是设备方向,一种是屏幕视图方向。我们可以直接调用[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPartrait];
强制更改设备方向,但该方法已经在iOS6中废止。另外一种更改设备方向的方法是通过重力感应触发。
那么视图方向是又什么决定的呢?
全局Info.plist
iOS6+在UIApplicationDelegate中增加了 - (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window;回调
UIViewController。并且只在UIWindow的rootViewController或model状态下的UIViewController有效
最终的视图方向取决于 (全局控制 ∩ UIWindow 中的回调 ∩ 单个界面控制) 的交集,如果交集为空,iOS6下抛出 UIApplicationInvalidInterfaceOrientationException 异常后崩溃。
UIController中对视图方向变化的响应
iOS5:-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return ((toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) | (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)); }iOS6+:
// 支持转屏? (BOOL)shouldAutorotate { return YES; } // 支持的屏幕方向 - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
实现前后的效果
竖屏:横屏:
两张横竖屏的图片中,菜单、标题大小都发生了改变。下面我们就来讨论下实现的方法。
实现细节
首先在视频播放所在UIViewController支持横竖屏,并在设备旋转的回调中,通知菜单当前的设备方向发生了改变,代码如下://设备旋转前 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { //横竖屏变更菜单等 if (toInterfaceOrientation == UIInterfaceOrientationPortrait) { //竖屏状态 } //设备旋转前 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { //对视图进行旋转处理,这里通过present一个新的UIViewController,暂不需要处理 } //设备旋转完 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { //设备旋转完的处理 } // 支持转屏 (BOOL)shouldAutorotate { return YES; } // 支持的屏幕方向 - (NSUInteger)supportedInterfaceOrientations { return UIDeviceOrientationLandscapeLeft | UIInterfaceOrientationPortrait ; } -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return ((toInterfaceOrientation == UIInterfaceOrientationPortrait) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)); }willRotateToInterfaceOrientation:duration: 和 willAnimateRotationToInterfaceOrientation:duration:的区别在于调用的顺序。前者在旋转前调用,并且屏幕方向、设备原点、视图大小等都未改变,后者在旋转的动画block中调用,并且屏幕方向、设备原点、视图大小等都已改变。因此在willRotateToInterfaceOrientation:duration:中,应当做变量的更改;在willAnimateRotationToInterfaceOrientation:duration:中,适合做一些重绘工作。
考虑到原来的视频播放器只支持横屏播放,这里采用的方案如下:竖屏状态下,先present一个只支持横屏的UIViewController,再将视频播放器作为横屏UIViewController的子控制器添加进来。这样可以触发iOS进行横竖屏检测。
当竖屏切到横屏时,旋转的动画设置。代码如下:
[portraitViewController presentViewController:landscapeViewController animated:NO completion:^{ //mvPlayer原先是作为protraitViewController的子UIViewController [mvPlayer.view removeFromSuperview]; [mvPlayer removeFromParentViewController]; //改为作为landscapeViewController的子UIViewController [landscapeViewController addChildViewController:mvPlayer]; [landscapeViewController.view addSubview:mvPlayer.view]; //改变状态栏方向 [[UIApplication sharedApplication] setStatusBarHidden:YES]; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:NO]; //旋转前 CGAffineTransform transform = CGAffineTransformMakeRotation(-M_PI_2); transform = CGAffineTransformScale(transform, scale, scale); mvPlayer.view.transform = transform; //旋转动画 [UIView animateWithDuration:[[UIApplication sharedApplication] statusBarOrientationAnimationDuration] animations:^{ mvPlayer.view.transform = CGAffineTransformIdentity; mvPlayer.view.frame = landscapeViewController.view.bounds; }completion:^(BOOL finished) { [[UIApplication sharedApplication] setStatusBarHidden:NO]; }]; }];
横屏切换到竖屏的动画实现如下:
//更改mvPlayer的父UIController [mvPlayer.view removeFromSuperview]; UIViewController *viewController = strongSelf.player.presentingViewController; [mvPlayer removeFromParentViewController]; [viewController dismissModalViewControllerAnimated:NO]; [portraitViewController addChildViewController:mvPlayer]; [portraitViewController.view addSubview:mvPlayer.view]; //缩放动画 CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale); mvPlayer.view.transform = transform; mvPlayer.view.frame = CGRectMake(0, 0, CGRectGetWidth(mvPlayer.view.frame), CGRectGetHeight(mvPlayer.view.frame)); mvPlayer.view.transform = CGAffineTransformRotate(transform, M_PI_2); [UIView animateWithDuration:[[UIApplication sharedApplication] statusBarOrientationAnimationDuration] animations:^{ mvPlayer.view.transform = CGAffineTransformMakeScale(scale, scale); } completion:^(BOOL finished) { mvPlayer.view.fram 4000 e = CGRectMake(0, 0, CGRectGetWidth(mvPlayer.view.frame), CGRectGetHeight(mvPlayer.view.frame)); }];
以上是手动旋转过程。还有一种方法是直接旋转portraitViewController.view。人为旋转过程中,设备的原点并未发生改变,这需要考虑横竖屏布局问题。
总结
本文介绍横竖屏切换的一些基础知识,并实践了类似腾讯视频的横竖屏人为切换方式,达到不同状态下显示不同视图的交互方式。相关文章推荐
- iOS 让只支持竖屏的App横屏播放网页视频
- ios 屏幕旋转,横屏竖屏
- ios 屏幕旋转,横屏竖屏
- 在IOS应用中从竖屏模式强制转换为横屏模式
- 在iOS应用中从竖屏模式强制转换为横屏模式
- iOS横屏竖屏旋转的方法(怕留网址会消失,直接复制内容过来了)
- 实现iOS全局禁止横屏,但kxmovie全屏横屏播放视频
- 说一下视频播放跟随屏幕旋转,以及activity涉及到的周期问题
- 在IOS应用中从竖屏模式强制转换为横屏模式
- iOS UIWebView 全屏播放视频, 需横屏,单app不支持横屏, 解决办法
- ios 只让播放视频的 时候能够全屏横屏 其他全部非全屏非横屏 目前已经测试很多 可以
- UIWebView中视频播放屏幕自动旋转,app不支持旋转但是某一个页面需要旋转等
- iOS 全局禁止横屏,但UIWebView 全屏横屏播放视频的解决办法
- (转)在IOS应用中从竖屏模式强制转换为横屏模式
- ios开发应用程序,如何限制只能竖屏展示,旋转横屏后界面无变化
- iOS UIWebView 全屏播放视频, 需横屏,单app不支持横屏, 解决办法
- (转)在IOS应用中从竖屏模式强制转换为横屏模式
- 菜鸟学android——webview播放网络视频,由竖屏转换为横屏全屏播放
- 视频录制与播放(竖屏)旋转90度问题
- iOS 全局禁止横屏,但UIWebView 全屏播放视频,横屏,解决办法