最近公司的iPhone端app要实现转屏的功能,所有顺便研究了一下ios转屏。下面将研究结果分享给大家。本文只是个人对ios转屏的理解,如有不对,欢迎指正。
先简单说下公司app转屏的需求。公司app有播放视频和查看摄像头的功能。要求视频播放界面和查看摄像头界面横屏,其他界面竖屏。本文只针对ios6.0以后的版本,至于和ios6.0以前版本的区别网上资料很多,大家可以自行查阅。
设置转屏有两种方法:
1、在工程general-deployment info-device orientation中勾选可以旋转的方向:有四种Portrait、Upside Down、Landscape Left、Landscape Right
2、在AppDelegate中添加方法:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
其中:UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown)
本文主要讲解第二种方法。
在不需要转屏的viewcontroller里添加下面两个方法,在需要转屏的viewcontroller里不添加就可以。
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate
{
return YES;
}
注意:ios6.0以后,转屏的逻辑判断放到了rootviewcontroller中了。所以如果在子viewcontroller里添加上述方法是不会响应的。要将根中的上述方法改成
引用:iOS6把转屏的逻辑判断放到了rootViewController里,也就是说,无论当前显示的是那个子vc,都是rootViewController响应转屏事件(或者present出来的modalViewController也可以,总之是最根部的vc才行),而且不向下传递。直接在一个childViewController里写这几个方法,是根本不会被调用到的。这就带来一个问题,根vc的转屏逻辑直接决定了子vc的转屏逻辑,如果老子说这个方向支持,那儿子只好支持,而且所有的儿子还都得支持。解决这个专制问题,可以在根vc里这样写:
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
引用:让老子每次转屏被问到的时候,都亲自问下他现在正在活跃的子孙。
转屏时调用顺序跟iOS5一样,不过shouldRotate被顺序拆分为shouldAutoRotate和supported。并且如果shouldAutoRotate返回了NO,则转屏过程中断,不再继续执行supported。
然后在相应的子viewcontroller中控制旋转与否。
屏幕旋转后会触发
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
CGRect frame;
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
[self.navigationController.navigationBar setHidden:NO];
frame = CGRectMake(0, 64, 320, 504);
[self.landImageView setFrame:frame];
[self.navigationController.view setFrame:CGRectMake(0, 0, 320, 568)];
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
[self.navigationController.navigationBar setHidden:YES];
frame = CGRectMake(0, 0, 568, 320);
[self.landImageView setFrame:frame];
[self.navigationController.view setFrame:frame];
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
[self.navigationController.navigationBar setHidden:YES];
frame = CGRectMake(0, 0, 568, 320);
[self.landImageView setFrame:frame];
[self.navigationController.view setFrame:frame];
}
}
查看摄像头转屏代码
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
CGFloat width = [UIScreen mainScreen].bounds.size.width;
CGFloat height = [UIScreen mainScreen].bounds.size.height;
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
view.transform = CGAffineTransformIdentity;
view.transform = CGAffineTransformMakeRotation(degreeToRadians(0));
view.frame = CGRectMake(0, 0, width,height );
}
else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
view.transform = CGAffineTransformIdentity;
view.transform = CGAffineTransformMakeRotation(degreeToRadians(-180));
view.frame = CGRectMake(0, 0, width,height );
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft)
{
view.frame = CGRectMake(-124, 124, height, width);
view.transform = CGAffineTransformIdentity;
view.transform = CGAffineTransformMakeRotation(degreeToRadians(-90));
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
view.frame = CGRectMake(-124, 124, height,width );
view.transform = CGAffineTransformIdentity;
view.transform = CGAffineTransformMakeRotation(degreeToRadians(90));
}
}
注意:转屏后view上的组件的大小需要根据实际情况进行调整。
获取当前屏幕方向用下面方法:
UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;