最近項目中有個分時圖的顯示需要進行橫屏處理。因為整個項目里面大部分頁面都是需要豎屏顯示的辜妓。只有幾個頁面是橫屏顯示矾克。
一.希望達到的效果
1.進行app默認的頁面顯示為豎屏,且不可切換橫豎屏捏鱼。
2.進行特定頁面的時候可以切換為橫屏执庐。且離開頁面進行豎屏頁面的時候可以自動顯示豎屏頁面。
3.保證push present和對應(yīng)的pop和dismiss正常顯示导梆。
二.解釋必要的幾個方法
- (BOOL)shouldAutorotate{
return NO;
}
此方法用來設(shè)置是否讓頁面支持自動旋轉(zhuǎn)屏幕轨淌,return YES既可以自動旋轉(zhuǎn)屏幕。NO就不能自動旋轉(zhuǎn)屏幕看尼。
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
此方法用來設(shè)置當前頁面支持的屏幕方向
UIInterfaceOrientationMask是一個枚舉递鹉,具體含義如下:
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),//向上為正方向的豎屏
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),//向左移旋轉(zhuǎn)的橫屏
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),//向右旋轉(zhuǎn)的橫屏
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),//向下為正方向的豎屏
UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),//向左或者向右的橫屏
UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),//所有的橫豎屏方向都支持
UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),//支持向上的豎屏和左右方向的橫屏
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
UIInterfaceOrientation是一個枚舉,取值如下
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,//屏幕方向未知
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,//向上正方向的豎屏
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,//向下正方向的豎屏
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,//向右旋轉(zhuǎn)的橫屏
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft//向左旋轉(zhuǎn)的橫屏
此方法用來設(shè)置當前頁面默認第一次進入的時候顯示的屏幕方向
三.實現(xiàn)原理講解
原理概述:
1.我們對項目的info.plist設(shè)置全局只支持橫屏藏斩,保證項目進入的時候自動進入橫屏躏结。
2.然后再使用以上三個方法對具體的每個控制器進行單獨的設(shè)置,保證每個控制器自身的橫屏豎屏表現(xiàn)合理灾茁。
三種情況:
- 沒被navigationController和tabBarController作為子控制器的Controller
- 在navigationController里面嵌套的Controller
- 在TabbarController里面嵌套的Controller
1.對于沒有被navigation和Tabbar嵌套窜觉,即跳轉(zhuǎn)方式如下的控制器:
UIViewController *vc = [[UIViewController alloc]init];
[self presentViewController:vc animated:YES completion:nil];
- (BOOL)shouldAutorotate{
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
只需要實現(xiàn)這個三個方法。像這樣的設(shè)置北专,即可保證Controller是豎屏的表現(xiàn)禀挫,且不可以自動進行橫屏豎屏切換。
2.對于被NavigationController嵌套的Controller.即跳轉(zhuǎn)方式如下的控制器
NaviViewController *navController = [[NaviViewController alloc]init];
QXNavigationViewController *navigationController = [[QXNavigationViewController alloc]initWithRootViewController:navController];
[self presentViewController:navigationController animated:YES completion:nil];
對于這樣的控制器我們除了需要在controller控制器里實現(xiàn)上面的三個方法之外拓颓,還需要在QXNavigationViewController(自定義)實現(xiàn)以下的方法:
- (BOOL)shouldAutorotate{
return [self.visibleViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return [self.visibleViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [self.visibleViewController preferredInterfaceOrientationForPresentation];
}
實現(xiàn)完成這三個方法即可保證语婴。navigationController的橫豎屏表現(xiàn)會依照他的rootViewController的設(shè)置來表現(xiàn)。
3.對于在TabbarController里面嵌套的Controller驶睦。即創(chuàng)建方式如下:
- (void)setInitTabBar{
NSArray *baseArray = @[@"ViewController",@"SecondViewController",@"NaviViewController"];
for (NSInteger i = 0; i < baseArray.count; i++){
Class cls = NSClassFromString(baseArray[i]);
QXNavigationViewController *naviController = [[QXNavigationViewController alloc]initWithRootViewController:[[cls alloc]init]];
[self addChildViewController:naviController];
}
}
controller作為tabbar的childViewController,依照第二種情況我們同樣需要在QXTabBarController里面實現(xiàn)三個方法砰左,保證tabbarController會依照它保存的子控制器的設(shè)置來渲染:
- (BOOL)shouldAutorotate{
return [self.selectedViewController shouldAutorotate];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
四.注意點
這種方式設(shè)置完成了以后會有一個小坑。就是從頁面A(豎屏狀態(tài))跳轉(zhuǎn)到NavigationController或者tabbarController包裹的控制器以后场航,如果控制器允許橫屏缠导。并且切換為橫屏,直接pop或者dismiss回來會讓頁面A仍然保持橫屏狀態(tài)溉痢。對于這個問題我的處理建議是:
1.如果是push進入的controller那么就在頁面A的viewWillAppear里面加上如下方法:
- (void)viewWillAppear:(BOOL)animated{
NSNumber * value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
2.如果是從頁面A present方式跳轉(zhuǎn)的頁面僻造、那么就將頁面A的方法
//- (BOOL)shouldAutorotate{
// return NO;
//}
注釋掉。
這些方法可以保證controller在返回頁面A的時候自動調(diào)整橫豎屏的顯示效果孩饼。
本文Demo
本文內(nèi)容皆為原創(chuàng)髓削,有任何問題歡迎各外朋友指正,一塊交流镀娶。
本文參考內(nèi)容為:燃燒的大叔
iOS 關(guān)于屏幕旋轉(zhuǎn)shouldAutorotate