首先我们要先设置app允许的窗口朝向
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;
如果你没有写这个方法,那会从plist里获取默认值。
该方法来自UIApplicationDelegate,所以要写在AppDelegate里。
所使用的枚举
typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {
UIInterfaceOrientationMaskPortrait,//home键朝下
UIInterfaceOrientationMaskLandscapeLeft,//home键朝左
UIInterfaceOrientationMaskLandscapeRight ,//home键朝右
UIInterfaceOrientationMaskPortraitUpsideDown,//home键朝上
UIInterfaceOrientationMaskLandscape,//home键朝左或者朝右
UIInterfaceOrientationMaskAll,//上下左右都可以
UIInterfaceOrientationMaskAllButUpsideDown,//home键朝左朝右朝下
}
swift写法
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait.union(UIInterfaceOrientationMask.landscapeLeft);
//可以竖屏和home键在左边横屏
}
OC写法
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
}
然后设置页面是否允许翻转和页面允许的方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
//默认值iPad UIInterfaceOrientationMaskAll iPhone UIInterfaceOrientationMaskAllButUpsideDown
- (BOOL)shouldAutorotate //默认值为YES
- (BOOL)prefersStatusBarHidden //默认值为YES
supportedInterfaceOrientations这个方法表示该view controller允许的朝向,但是这个方向必须是application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window中或者plist中允许的方向。
横屏的时候状态栏会默认隐藏。所以我们需要设置prefersStatusBarHidden
OC
- (BOOL)shouldAutorotate {
return YES;
}
- (BOOL)prefersStatusBarHidden {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
Swift
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait.union(UIInterfaceOrientationMask.landscapeRight.union(UIInterfaceOrientationMask.portraitUpsideDown))
}
override var prefersStatusBarHidden: Bool {
return false
}
这三个方法都是UIViewController下。也就是说UIViewcontroller及他的子类都可以用这三个方法(UITabBarController, UINavigationController也是UIViewcontroller的子类)。
如果rootViewController为UITabBarController实例的时候。
只有UITabBarController的shouldAutorotate起作用。UITabBarController下的UINavigationController和UIViewcontroller的shouldAutorotate都有不能控制窗口翻转,但是UIViewcontroller的shouldAutorotate为YES时可以造成状态栏的翻转,状态栏的翻转方向受UIViewcontroller的supportedInterfaceOrientations影响。
效果如下:
如果rootViewController为UINavigationController实例的时候。UIViewcontroller的shouldAutorotate为YES时可以造成状态栏的翻转但是不会对窗口的翻转有影响。状态栏的翻转方向受UIViewcontroller的supportedInterfaceOrientations影响。
由UIViewcontroller present出来的页面不受rootViewController的影响。翻转情况由他自己的shouldAutorotate和supportedInterfaceOrientations控制。
强制翻转:
当退出可翻转页面的时候我们往往会用到强制翻转。原理就是一个KVC。
OC
//先判断Orientation状态
if ((long)self.preferredInterfaceOrientationForPresentation != 1) {
NSNumber *orientationUnknown = [NSNumber numberWithInt:UIInterfaceOrientationUnknown];
[[UIDevice currentDevice] setValue:orientationUnknown forKey:@"orientation"];
NSNumber *orientationTarget = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:orientationTarget forKey:@"orientation"];
}
Swift
//注意在swift中系统不能将enum直接转成int型,所以需要手动get rawValue
if self.preferredInterfaceOrientationForPresentation != .portrait {
UIDevice.current.setValue(NSNumber.init(value: UIDeviceOrientation.unknown.rawValue), forKey: "orientation")
UIDevice.current.setValue(NSNumber.init(value: UIDeviceOrientation.portrait.rawValue), forKey: "orientation")
}