UIDeviceOrientation指的是设备的物理方向,一共有下面七种方向。
public enum UIDeviceOrientation : Int { case unknown case portrait // Device oriented vertically, home button on the bottom case portraitUpsideDown // Device oriented vertically, home button on the top case landscapeLeft // Device oriented horizontally, home button on the right case landscapeRight // Device oriented horizontally, home button on the left case faceUp // Device oriented flat, face up case faceDown // Device oriented flat, face down }通过UIDevice.current.orientation可以获取当前设备方向,当设备方向变化时,会发出UIDevice.orientationDidChangeNotification通知,监听该通知可以处理设备方向改变事件。
override func viewDidLoad() { super.viewDidLoad() //监听通知前判断是否在生成设备方向通知了,没有的话调用beginGeneratingDeviceOrientationNotifications() if !UIDevice.current.isGeneratingDeviceOrientationNotifications{ UIDevice.current.beginGeneratingDeviceOrientationNotifications() } NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil) } @objc func deviceOrientationDidChange(sender: AnyObject) { print(UIDevice.current.orientation.rawValue) } deinit { NotificationCenter.default.removeObserver(self) }UIInterfaceOrientation指的是界面方向,一共有下面5种方向。
public enum UIInterfaceOrientation : Int { case unknown case portrait case portraitUpsideDown case landscapeLeft case landscapeRight }UIInterfaceOrientation和状态栏有关,通过UIApplication.shared.statusBarOrientation可以获取当前界面方向。监听 UIApplication.willChangeStatusBarOrientationNotification和UIApplication.didChangeStatusBarOrientationNotification可以处理界面方向改变事件。
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(interfaceOrientationWillChange), name: UIApplication.willChangeStatusBarOrientationNotification,object: nil) NotificationCenter.default.addObserver(self, selector: #selector(interfaceOrientationDidChange), name: UIApplication.didChangeStatusBarOrientationNotification,object: nil) } @objc func interfaceOrientationWillChange(sender: AnyObject) { print("interfaceOrientationWillChange:\(UIApplication.shared.statusBarOrientation.rawValue)") } @objc func interfaceOrientationDidChange(sender: AnyObject) { print("interfaceOrientationDidChange:\(UIApplication.shared.statusBarOrientation.rawValue)") } deinit { NotificationCenter.default.removeObserver(self) }UIKit接收到设备方向改变事件后,通过AppDelegate通知当前程序的UIWindow对象,UIWindow对象通知它的rootViewController,如果该rootViewController支持改变后的界面方向,则改变界面方向。
修改UIApplicationDelegate的supportedInterfaceOrientationsFor方法可以指定App支持的界面方向,该方法的默认值为Info.plist的Supported interface orientations(也可以通过General=>Deployment Info=>Device Orientation修改)。
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .allButUpsideDown }UIViewController可以通过重写supportedInterfaceOrientations修改支持的界面方向,重写preferredInterfaceOrientationForPresentation修改显示的界面方向,这些界面方向不能包含App不支持的界面方向。
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{ get{ return .portrait } } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{ get{ return .portrait } }当UIViewController显示在UINavigationController或UITabBarController中时,支持的界面方向为UINavigationController或UITabBarController支持的界面方向。
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{ get{ return visibleViewController?.supportedInterfaceOrientations ?? .portrait } } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{ get{ return visibleViewController?.preferredInterfaceOrientationForPresentation ?? .portrait } } override var supportedInterfaceOrientations: UIInterfaceOrientationMask{ get{ return selectedViewController?.supportedInterfaceOrientations ?? .portrait } } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{ get{ return selectedViewController?.preferredInterfaceOrientationForPresentation ?? .portrait } }UIDeviceOrientation只能读取不能修改,UIInterfaceOrientation可以通过attemptRotationToDeviceOrientation将界面方向修改为与设备方向一致。修改支持的界面方向并不影响设备方向改变通知,例如支持的界面方向为仅竖屏,当手机横屏时依然会收到设备方向改变通知。