我使用以下代码查看设备是否处于横向模式:
UIDevice.currentDevice().orientation.isLandscape.boolValue
但是,如果我在启动应用程序之前将设备置于横向模式,则可以正常工作,之后再viewDidLoad
调用此代码行,则始终返回false
。
如果我改用这个:
interfaceOrientation.isLandscape
它返回true
,这是正确的,但是编译器正在显示警告interfaceOrientation was deprecated in iOS 8.0
。
启动应用后立即获得设备定位的正确方法是什么?
DeviceOrientation vs.ScreenSize vs StatusBar.isLandscape?
iOS 11,Swift 4和Xcode 9.X
无论是否使用AutoLayout,都有几种方法来获取正确的设备方向,它们可以用于检测使用应用程序时的旋转变化,以及在应用程序启动时或从后台恢复后获取正确的方向。
此解决方案在iOS 11和Xcode 9.X中可以正常工作
1. UIScreen.main.bounds.size:
如果你只是想知道,如果应用程序是在横向或纵向模式,最好的点开始是viewDidLoad
在rootViewController
在启动时和viewWillTransition(toSize:)
在rootViewController
如果要检测旋转的变化,而该应用程序在后台运行,应以正确的方向恢复用户界面。
let size = UIScreen.main.bounds.size if size.width < size.height { print("Portrait: \(size.width) X \(size.height)") } else { print("Landscape: \(size.width) X \(size.height)") }
这也发生在app / viewController生命周期的早期。
2. NotificationCenter
如果您需要获取实际的设备方向(包括faceDown,faceUp等)。您想按如下方式添加观察者(即使您在中的application:didFinishLaunchingWithOptions
方法中添加了观察者,AppDelegate
也可能在viewDidLoad
执行之后触发第一个通知
device = UIDevice.current device?.beginGeneratingDeviceOrientationNotifications() notificationCenter = NotificationCenter.default notificationCenter?.addObserver(self, selector: #selector(deviceOrientationChanged), name: Notification.Name("UIDeviceOrientationDidChangeNotification"), object: nil)
并按如下所示添加选择器。我在第2个部分拆分它能够运行inspectDeviceOrientation()
在viewWillTransition
@objc func deviceOrientationChanged() { print("Orientation changed") inspectDeviceOrientation() } func inspectDeviceOrientation() { let orientation = UIDevice.current.orientation switch UIDevice.current.orientation { case .portrait: print("portrait") case .landscapeLeft: print("landscapeLeft") case .landscapeRight: print("landscapeRight") case .portraitUpsideDown: print("portraitUpsideDown") case .faceUp: print("faceUp") case .faceDown: print("faceDown") default: // .unknown print("unknown") } if orientation.isPortrait { print("isPortrait") } if orientation.isLandscape { print("isLandscape") } if orientation.isFlat { print("isFlat") } }
请注意,UIDeviceOrientationDidChangeNotification
在启动过程中可能会多次发布,有时甚至是.unknown
。我所看到的是,第一个正确的定向通知是在viewDidLoad
和viewWillAppear
方法之后,正好在viewDidAppear
甚至是之前收到的applicationDidBecomeActive
方向对象将为您提供所有7种可能的方案(根据enum 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 }
有趣的是,isPortrait
只读Bool
变量在扩展中定义UIDeviceOrientation
如下:
extension UIDeviceOrientation { public var isLandscape: Bool { get } public var isPortrait: Bool { get } public var isFlat: Bool { get } public var isValidInterfaceOrientation: Bool { get } }
3. StatusBarOrientation
UIApplication.shared.statusBarOrientation.isLandscape
这也可以很好地确定方向是纵向还是横向,并获得与点1相同的结果。您可以在viewDidLoad
(用于应用启动)和viewWillTransition(toSize:)
来自背景的情况下对其进行评估。但这不会为您提供通过通知获得的顶部/底部,左/右,上/下的详细信息(第2点)