我想知道如何在Swift中获取当前设备方向?我知道有Objective-C的示例,但我无法让它在Swift中工作。
我正在尝试获取设备方向并将其放入if语句中。
这是我遇到最大问题的那一行:
[[UIApplication sharedApplication] statusBarOrientation]
我想知道如何在Swift中获取当前设备方向?我知道有Objective-C的示例,但我无法让它在Swift中工作。
我正在尝试获取设备方向并将其放入if语句中。
这是我遇到最大问题的那一行:
[[UIApplication sharedApplication] statusBarOrientation]
你可以使用:
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
var text=""
switch UIDevice.currentDevice().orientation{
case .Portrait:
text="Portrait"
case .PortraitUpsideDown:
text="PortraitUpsideDown"
case .LandscapeLeft:
text="LandscapeLeft"
case .LandscapeRight:
text="LandscapeRight"
default:
text="Another"
}
NSLog("You have moved: \(text)")
}
SWIFT 3升级
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
var text=""
switch UIDevice.current.orientation{
case .portrait:
text="Portrait"
case .portraitUpsideDown:
text="PortraitUpsideDown"
case .landscapeLeft:
text="LandscapeLeft"
case .landscapeRight:
text="LandscapeRight"
default:
text="Another"
}
NSLog("You have moved: \(text)")
}
或者override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
}
使用通知,您可以检查:IOS8 Swift:如何检测方向更改?
注意:didRotateFromInterfaceOrientation已弃用,请在iOS 2.0及更高版本中使用viewWillTransitionToSize
如果面朝上或面朝下则无法使用此方法。因此我们需要使用以下方法。
if UIApplication.shared.statusBarOrientation.isLandscape {
// activate landscape changes
} else {
// activate portrait changes
}
super.didRotate(from: fromInterfaceOrientation)
。根据苹果文档:“您必须在执行过程中的某个时刻调用此方法的超级方法。” - Bocaxica要像Objective-C代码一样获取状态栏(因此UI)方向,只需执行以下操作:
UIApplication.sharedApplication().statusBarOrientation
您还可以使用UIDevice的orientation
属性:
UIDevice.currentDevice().orientation
然而,这可能与您的用户界面(UI)的方向不匹配。从文档中可以看到:
该属性的值是指示设备当前方向的常量。此值表示设备的物理方向,可能与应用程序用户界面的当前方向不同。请参见“UIDeviceOrientation”以了解可能值的描述。
UIDevice.current.orientation
也可以使用。 - Mustafa Demirstruct DeviceInfo {
struct Orientation {
// indicate current device is in the LandScape orientation
static var isLandscape: Bool {
get {
return UIDevice.current.orientation.isValidInterfaceOrientation
? UIDevice.current.orientation.isLandscape
: UIApplication.shared.statusBarOrientation.isLandscape
}
}
// indicate current device is in the Portrait orientation
static var isPortrait: Bool {
get {
return UIDevice.current.orientation.isValidInterfaceOrientation
? UIDevice.current.orientation.isPortrait
: UIApplication.shared.statusBarOrientation.isPortrait
}
}
}}
Swift 4的答案:这就是我做的方式,
1.适用于所有类型的视图控制器
2.当用户旋转应用程序时也适用
3.也适用于第一次安装应用程序
苹果最近放弃了横屏和竖屏的概念,而更喜欢我们使用屏幕尺寸。不过,以下方式仍然有效:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("landscape")
} else {
print("portrait")
}
}
Swift 4:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("landscape")
} else {
print("portrait")
}
}
要找到当前设备的方向,只需使用以下代码:
UIApplication.sharedApplication().statusBarOrientation
对于Swift 3.0:
UIApplication.shared.statusBarOrientation
UIDevice.current.orientation
不同,UIApplication.shared.statusBarOrientation
在初始加载时就可用,而不仅仅是在屏幕旋转后。 - ewizardstatusBarOrientation已经被弃用,所以不能再像之前的答案那样使用它了。
此代码可获取方向而无需担心弃用问题。Swift 5 iOS 13.2 测试100%通过。
您的应用程序应允许在横屏和竖屏之间工作,才能使用以下代码,否则结果将不同。
windows.first 是主窗口windows.last 是当前窗口
struct Orientation {
// indicate current device is in the LandScape orientation
static var isLandscape: Bool {
get {
return UIDevice.current.orientation.isValidInterfaceOrientation
? UIDevice.current.orientation.isLandscape
: (UIApplication.shared.windows.first?.windowScene?.interfaceOrientation.isLandscape)!
}
}
// indicate current device is in the Portrait orientation
static var isPortrait: Bool {
get {
return UIDevice.current.orientation.isValidInterfaceOrientation
? UIDevice.current.orientation.isPortrait
: (UIApplication.shared.windows.first?.windowScene?.interfaceOrientation.isPortrait)!
}
}
}
Swift 3+
基本上:
NotificationCenter.default.addObserver(self, selector: #selector(self.didOrientationChange(_:)), name: .UIDeviceOrientationDidChange, object: nil)
@objc func didOrientationChange(_ notification: Notification) {
//const_pickerBottom.constant = 394
print("other")
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
print("landscape")
case .portrait, .portraitUpsideDown:
print("portrait")
default:
print("other")
}
}
:)
func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
,因为traitcollection始终是width.regular
和height.regular
,因此在旋转时traitCollection不会改变。在Swift 4中,通知已重命名为UIDevice.orientationDidChangeNotification
。 - Bocaxica我使用InterfaceOrientation
时出了问题,它的工作还好,除了在加载时无法访问方向。所以我尝试了这个方法,它非常可靠。这样做是因为bounds.width
始终参照当前方向,而不是绝对值nativeBounds.width
。
if UIScreen.mainScreen().bounds.height > UIScreen.mainScreen().bounds.width {
// do your portrait stuff
} else { // in landscape
// do your landscape stuff
}
我从willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)
和viewDidLoad
中调用它,但它是灵活的。
感谢zSprawl指出了这个方向。需要指出的是,这仅适用于iOS 8及更高版本。
因此,如果苹果公司已经弃用了整个方向字符串的概念("portrait",“landscape”),那么你只需要关心宽度与高度的比率。这有点像 @bpedit 的回答。
当你将宽度除以高度时,如果结果小于1,则 mainScreen 或容器或其他任何东西处于“竖屏”模式。如果结果大于1,则为“横屏”绘画。 ;)
override func viewWillAppear(animated: Bool) {
let size: CGSize = UIScreen.mainScreen().bounds.size
if size.width / size.height > 1 {
print("landscape")
} else {
print("portrait")
}
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if size.width / size.height > 1 {
print("landscape")
} else {
print("portrait")
}
}
我猜如果你使用这种方法,那么你可能并不真的关心当比率恰好为1时的特定处理条件,即宽度和高度相等。super.viewWillAppear(animated)
和 super.viewWillTransition(to: size, with: coordinator)
。 - Bocaxica