我使用以下代码查看设备是否处于横向模式:
UIDevice.currentDevice().orientation.isLandscape.boolValue
如果我在启动应用程序之前将设备置于横向模式,并且在viewDidLoad
之后,我调用这行代码,它总是会返回false
。
如果我改用它:
interfaceOrientation.isLandscape
它返回true
,这是正确的,但编译器显示警告interfaceOrientation was deprecated in iOS 8.0
。
在应用启动后立即获取设备方向的正确方法是什么?
答案 0 :(得分:6)
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
如果你想在应用程序处于后台时检测旋转变化,并且应该以正确的方向恢复UI。
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。通知中心强>
如果您需要获取实际的设备方向(包括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)
按如下方式添加选择器。我将其拆分为两部分,以便能够在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点)向您提供上/下,左/右,上/下的详细信息
答案 1 :(得分:1)
在检查方向isValidInterfaceOrientation
之前应检测到isLandscape
。 不要用 isValidInterfaceOrientation == false
处理文本消息(当它的值为isLandscape
时)。
在对此进行更仔细的阅读之前,我对此感到不知所措。考虑到isValidInterfaceOrientation
,效果很好。
@objc func rotated() {
if (UIDevice.current.orientation.isValidInterfaceOrientation) {
if (UIDevice.current.orientation.isLandscape) {
if(!bLandscape) {
bLandscape = true
setupTabBar() // Repaint the app
}
} else { // Portait
if(bLandscape) {
bLandscape = false
setupTabBar() // Repaint the app
}
}
}
}
答案 2 :(得分:0)
我已多次测试过方向,所以我总结了一些经验。
在除iPhone6之外的所有iPhone设备中,唯一的界面方向是.portrait
。如果App以横向模式启动,则必须更改方向。一个人将收到UIDeviceOrientationDidChangeNotification
。现在是获得指导的合适时间。
关于使用iPhone6进行横向启动时,启动后的方向将改变一次:
使用iPhone6 plus进行横向启动时,启动后方向永远不会改变:
因此,在应用更改方向之前,方向仍然与主页中的方向相同。
在viewDidLoad
中,方向尚未更改,日志将是错误的方向。
答案 3 :(得分:0)
我在检测isFlat之前哪个方向时遇到问题,因此我将其放入视图控制器中
let orientation = UIDevice.current.orientation
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if orientation.isPortrait {
return .portrait
} else if orientation.isFlat{
if UIScreen.main.bounds.width < UIScreen.main.bounds.height{
return .portrait
} else {
return .landscape
}
} else {
return .landscape
}
}
答案 4 :(得分:0)
这对我有用:
if UIScreen.main.bounds.width > UIScreen.main.bounds.height{
print("Portraitmode!")
}
它可以根据显示尺寸在所有设备上使用: https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html