横竖屏监听和强制设置
前言:监听是做到了,但是乱七八糟。 (version >= iOS 8 )
设置横竖屏的方式和优先级
遇到问题:
之前有个项目同时设置了 UIWindow 级别 和 UIViewController 级别,但是后者完全被前者覆盖。UIWindow 设置 Portrait 和 Landscape ,然后你在 UIViewController 中设置 Portrait ,没什么用。只有 UIViewController 出现时才会设置一下 Portrait ,但是每次旋转时询问的是 UIWindow 中的设置。这样会给维护人员造成一定的困扰。
个人建议:
如果实现了 UIWindow 级别,就别再实现 UIViewController 级别。
1. 应用级:
设置 info.plist 文件或者在 General 中设置。优先级最高,如果这里不容许横屏,后面不管怎么设置也无法横屏。
2. UIWindow 级:
在 AppDelegate 中实现代理接口: -application: supportedInterfaceOrientationsForWindow:
注意点:
当手机想要变换的状态和当前手机屏幕状态不一致时,这个接口才会调用。比如:当前 App 只支持 Portrait , 将手机横放 , 此时这个接口会被调用。但是,此时将手机回复到竖放位置,这个接口不会调用。
3. UIViewController 级:
个人建议:
如果你的 App 大量用到了横屏才考虑这个。到时候再去查查资料。
使用应用级和 UIWindow 级设置
你可以使用一个全局变量来对-application: supportedInterfaceOrientationsForWindow:
的返回值进行管理。
/**
* window 支持旋转方向
*/
typedef NS_ENUM(NSInteger , CHInterfaceOrientationStatus) {
/**
* 竖屏
*/
CHInterfaceOrientationStatusPortrait,
/**
* 横屏
*/
CHInterfaceOrientationStatusLandscape,
/**
* 横竖屏
*/
CHInterfaceOrientationStatusPL,
};
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window {
switch (self.orientationStatus) {
case CHInterfaceOrientationStatusPortrait: {
return UIInterfaceOrientationMaskPortrait;
break;
}
case CHInterfaceOrientationStatusLandscape: {
return UIInterfaceOrientationMaskLandscape;
break;
}
case CHInterfaceOrientationStatusPL: {
return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationPortrait;
break;
}
default: {
return UIInterfaceOrientationMaskAll;
break;
}
}
}
这样在希望横屏的 UIViewController 中设置这个变量的值就可以灵活的设置该 UIViewController 支持的方向了。
监听横竖屏
iOS 8 之后监听横竖屏的接口变化。
个人推荐:UIApplicationDidChangeStatusBarOrientationNotification
或者-viewWillTransitionToSize: withTransitionCoordinator:
使用:
在需要监听的 UIViewController 中监听 UIApplicationDidChangeStatusBarOrientationNotification 或者 实现 -viewWillTransitionToSize: withTransitionCoordinator: 这个接口。
说明:
还有很多其他方式也可以监听,比如 UITraitCollection 的代理接口等。但是够用就可以了。
强制横竖屏
前提: 支持所设置的方向,按照下面的就是必须支持 UIInterfaceOrientationLandscapeRight
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];