iOS屏幕方向适配
KeyWords
shouldAutorotate
supportedInterfaceOrientations
PreferedInterfaceOrientationForPresentation
supportedInterfaceOrientationsForWindow
代码片段:
Tabbar
- (BOOL)shouldAutorotate {
return [self.selectedViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return self.selectedViewController.preferredInterfaceOrientationForPresentation;
}
NavigationBar
- (BOOL)shouldAutorotate
{
if ([self.topViewController isKindOfClass:[TDActivityViewController class]]) {
return [self.topViewController shouldAutorotate];
}
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if ([self.topViewController isKindOfClass:[TDActivityViewController class]]) {
return [self.topViewController supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
if ([self.topViewController isKindOfClass:[TDActivityViewController class]]) {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
return UIInterfaceOrientationPortrait;
}
UIViewController
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (!isProtrait) { return UIInterfaceOrientationMaskLandscapeRight;}
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
if (!isProtrait) { return UIInterfaceOrientationLandscapeRight;}
return UIInterfaceOrientationPortrait;
}
代码设置屏幕方向
/// 设置竖屏
if([[UIDevice currentDevice]respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice]performSelector:@selector(setOrientation:)
withObject:[NSNumber numberWithInt:UIInterfaceOrientationPortrait]];
}
/// 设置横屏
if([[UIDevice currentDevice]respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice]performSelector:@selector(setOrientation:)
withObject:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight]];
}
Push 和 Present视图方式
Push方式的视图旋转控制是由其父控制器逐步向子控制器传递控制,类似于响应链。
我们看看视图层次:
UITabBarController
- UINavigationController
-
TDActivityViewController
-
UINavigationConttroller
- UIViewController2
如果要控TDActivityViewController
的旋转方向,除了TDActivityViewController
设置旋转,还要在它父控制器设置,这样的一个传递过程:
UITabBarController -> UINavigationController -> TDActivityViewController
,具体参考代码片段。
Present方式的视图旋转控制是由其本身控制器来做控制,与弹出该控制器的主控制器无关。
UITabBarController
- UINavigationController
-
UIViewController1
-
UINavigationConttroller
-
UIViewController2
- UIViewController3 (Present方式)
如果要控制UIViewController3的旋转方向,则只需要在UIViewController3里面设置旋转即可。不需要在它父控制器设置。
PreferedInterfaceOrientationForPresentation方法
这个方法是设置PresentViewController的方向,在UIViewController3里面添加该方法返回想要的方向(注:如果有NavigationController父控制器,则需要在父控制器逐步传递下来, NavigationController->UIViewController3)
当dismissViewController的时候,还会在UITabBarController调用一次PreferedInterfaceOrientationForPresentation方法,这个方法是设置dismissViewController完之后,需要恢复设置的方向。
横屏进入竖屏约束错误问题
当横屏进入竖屏的时候,竖屏获取宽度是为横屏的宽度。
如果是在viewDidLoad读取屏幕宽度,会读取成横屏的屏幕宽度,这是横竖屏适配的问题。
Crash
1.supported orientations has no common orientation with the application
应用程序只支持竖屏,但是在ViewController中你返回横屏
2. Present视图,Dismiss视图Crash.
模态弹出控制器 preferredInterfaceOrientationForPresentation
控制器dismiss时候回调用 所在控制器 supportedInterfaceOrientations
如果返回的和preferredInterfaceOrientationForPresentation不一致,则会crash,supportedInterfaceOrientations 里面的值必须要大于或者等于preferredInterfaceOrientationForPresentation
Ques:
1.分享回来后,原来是横屏显示,恢复成竖屏方向。
这个是因为,横屏显示的时候,Present一个分享框(支持OrientationMaskAllButUpsideDown),这时候,屏幕是支持旋转的。返回的时候,分享框恢复成为protrait,从而修改了横屏显示。如果需要保持原来横屏显示,则分享框不允许旋转即可。