iOS实现横竖屏切换,需注意两种情况,即强制/非强制,否则容易造成代码无法实现预计切换效果。
1、横竖屏切换情况:
1.1、上图红框中 Left,Right 勾选,表示APP支持横屏,属于非强制横竖屏切换情况
1.2、上图红框中 Left,Right 都不勾选,表示APP不支持横屏,属于强制横竖屏切换情况
备注:后述中代码中"isPortrait"变量用于记录横/竖屏状态
2、横竖屏转换实现,有两种方法:
2.1、KVC实现
if isPortrait {
//切换到横屏
UIDevice.current.setValue(NSNumber(integerLiteral: UIInterfaceOrientation.landscapeLeft.rawValue), forKey: "orientation")
isPortrait = false
} else {
//切换到竖屏
UIDevice.current.setValue(NSNumber(integerLiteral: UIInterfaceOrientation.portrait.rawValue), forKey: "orientation")
isPortrait = true
}
2.2、NSInvocation实现
#import <UIKit/UIKit.h>
@interface DeviceOrientationTool : NSObject
+ (void)interfaceOrientation:(UIInterfaceOrientation)orientation;
@end
#import "DeviceOrientationTool.h"
@implementation DeviceOrientationTool
+ (void)interfaceOrientation:(UIInterfaceOrientation)orientation {
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = (int)orientation;
[invocation setArgument:&val atIndex:2];
[invocation invoke];
}
}
@end
if AppDelegate.isPortrait {
//切换到横屏
AppDelegate.isPortrait = false
DeviceOrientationTool.interfaceOrientation(.landscapeLeft)
} else {
//切换到竖屏
AppDelegate.isPortrait = true
DeviceOrientationTool.interfaceOrientation(.portrait)
}
3、强制/非强制横竖屏切换
3.1、非强制横竖屏切换:
结合2.1部分代码,并在相关VC中复写如下属性即可(如果需要支持自转)
override var shouldAutorotate: Bool {
return true
}
3.2、强制横竖屏切换:
结合2.2部分代码,并在AppDelete中实现如下方法即可
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if AppDelegate.isPortrait {
return [.portrait]
}
return [.portrait, .landscapeLeft, .landscapeRight]
}
备注:3.1和3.2可使用2.1或2.2部分代码
4、监听屏幕方向变化
NotificationCenter.default.addObserver(self, selector: #selector(orientationChangedNotification(_:)), name: UIDevice.orientationDidChangeNotification, object: UIDevice.current)
@objc func orientationChangedNotification(_ sender: Notification) {
let orientation = UIApplication.shared.statusBarOrientation
switch orientation {
case .landscapeLeft:
print("屏幕向左")
case .landscapeRight:
print("屏幕向右")
case .portrait:
print("屏幕向上")
case .portraitUpsideDown:
print("屏幕向下")
default:
print("未知方向")
}
}
5、iOS13及以上系统,在横屏状态下状态栏会消失
如果仍需显示状态栏,可参考类似思路:iOS13关于状态栏在横屏模式下隐藏的解决办法