Ios 在Swift中获取设备方向
我想知道如何在Swift中获取当前设备方向?我知道Objective-C有一些例子,但是我还没能在Swift中使用它 我正在尝试获取设备方向,并将其放入if语句中 这是我遇到最多问题的一条线:Ios 在Swift中获取设备方向,ios,swift,orientation,Ios,Swift,Orientation,我想知道如何在Swift中获取当前设备方向?我知道Objective-C有一些例子,但是我还没能在Swift中使用它 我正在尝试获取设备方向,并将其放入if语句中 这是我遇到最多问题的一条线: [[UIApplication sharedApplication] statusBarOrientation] 要获得与Objective-C代码类似的状态栏(以及UI)方向,只需: UIApplication.sharedApplication().statusBarOrientation 您还可
[[UIApplication sharedApplication] statusBarOrientation]
要获得与Objective-C代码类似的状态栏(以及UI)方向,只需:
UIApplication.sharedApplication().statusBarOrientation
您还可以使用UID设备:
UIDevice.currentDevice().orientation
但是,这可能与UI的方向不匹配。从文档中:
该属性的值是一个指示电流的常量
设备的方向。此值表示物理值
设备的方向可能与电流不同
应用程序用户界面的方向。看见
“UIDeviceOrientation”用于描述可能的值
您可以使用:
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)")
}
或
通过通知,您可以检查:
注意:didRotateFromInterfaceOrientation不推荐使用
iOS 2.0及更高版本的ViewwillTransitionOnToSize
在正面朝上和正面朝下的情况下,这将不起作用。
因此,我们需要使用以下方法
if UIApplication.shared.statusBarOrientation.isLandscape {
// activate landscape changes
} else {
// activate portrait changes
}
苹果最近摒弃了横向与纵向的概念,更喜欢使用屏幕大小。然而,这是可行的:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.currentDevice().orientation.isLandscape.boolValue {
print("landscape")
} else {
print("portrait")
}
}
我在使用
接口定向时遇到了问题,它工作正常,只是加载时没有访问定向。所以我试过这个,它是一个守门员。这是因为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(到InterfaceOrientation:
UIInterfaceOrientation,duration:NSTimeInterval)
和fromviewDidLoad
但它很灵活
多亏了zSprawl在那个方向的指针。我应该指出,这只适用于iOS 8及更高版本。因此,如果苹果不喜欢整个方向字符串(“纵向”、“横向”),那么你所关心的就是宽度与高度的比率。(有点像@bpedit的答案)
将宽度除以高度时,如果结果小于1,则主屏幕或容器或处于“纵向”模式的任何内容。如果结果大于1,则为“风景画”。)
(我猜如果你使用这种方法,那么你可能并不真正关心具体处理比率正好为1、宽度和高度相等的情况。)要查找当前设备方向,只需使用以下代码:
UIApplication.sharedApplication().statusBarOrientation
适用于swift 3.0
UIApplication.shared.StatusBaroOrientation
Swift 3,基于Rob的回答
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if (size.width / size.height > 1) {
print("landscape")
} else {
print("portrait")
}
}
swift4回答:
我就是这样做的
1.适用于各种视图控制器
2.在用户旋转应用程序时也可以工作
3.也是第一次安装应用程序Swift 4:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("landscape")
} else {
print("portrait")
}
}
// app start
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let orientation = self.view.window?.windowScene?.interfaceOrientation {
let landscape = orientation == .landscapeLeft || orientation == .landscapeRight
}
}
// on rotation
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let landscape = UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight
}
斯威夫特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")
}
}
:)我发现Swift中的替代代码是Obj-C代码
if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
是
注意:我们正在尝试查找状态栏方向是否为横向。如果是横向的,则If语句为真
statusBaroOrientation已被弃用,因此不再可用
在上述答案中
在这段代码中,您可以在不担心折旧的情况下获得方向Swift 5
ioS 13.2100%测试
您的应用程序应允许在纵向和横向两种情况下使用以下代码,否则,结果将不同
窗口。首先是主窗口
窗口。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)!
}
}
}
尝试使用horizontalSizeClass
和verticalSizeClass
:
import SwiftUI
struct DemoView: View {
@Environment(\.horizontalSizeClass) var hSizeClass
@Environment(\.verticalSizeClass) var vSizeClass
var body: some View {
VStack {
if hSizeClass == .compact && vSizeClass == .regular {
VStack {
Text("Vertical View")
}
} else {
HStack {
Text("Horizontal View")
}
}
}
}
}
在这里面找到的。相关苹果的。对于任何看到iOS 13的人:
对我来说,最可靠的方法现在已经被弃用了,尽管它(仍然)有效:
现在应该怎么做:
if UIApplication.shared.windows.first?.
windowScene?.interfaceOrientation.isPortrait ?? true {
print("Portrait")
} else {
print("Landscape")
}
Swift 5–解决方案:在应用程序启动和设备旋转期间检查方向:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("landscape")
} else {
print("portrait")
}
}
// app start
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let orientation = self.view.window?.windowScene?.interfaceOrientation {
let landscape = orientation == .landscapeLeft || orientation == .landscapeRight
}
}
// on rotation
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let landscape = UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight
}
Swift 5
适用于SwiftUI和基于情节提要的应用程序。另外,检查旋转和特征处理程序:
struct Orientation {
/// true - if landscape orientation, false - else
static var isLandscape: Bool {
orientation?.isLandscape ?? window?.windowScene?.interfaceOrientation.isLandscape ?? false
}
/// true - if portrait orientation, false - else
static var isPortrait: Bool {
orientation?.isPortrait ?? (window?.windowScene?.interfaceOrientation.isPortrait ?? false)
}
/// true - if flat orientation, false - else
static var isFlat: Bool {
orientation?.isFlat ?? false
}
/// valid orientation or nil
static var orientation: UIDeviceOrientation? {
UIDevice.current.orientation.isValidInterfaceOrientation ? UIDevice.current.orientation : nil
}
/// Current window (for both SwiftUI and storyboard based app)
static var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return UIApplication.shared.windows.first
}
return window
}
}
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
layoutAll()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("viewWillTransition")
layoutAll()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
print("traitCollectionDidChange")
layoutAll()
}
/// Layout content depending on the orientation
private func layoutAll() {
// Layout as you need
print("layoutAll: isLandscape=\(Orientation.isLandscape), isPortrait=\(Orientation.isPortrait), traitCollection=\(traitCollection)")
}
}
你有什么问题?将其转换为Swift或获得您期望的值?设备方向不一定与您的UI方向匹配。套管点-将设备平放并测试代码!我会注意到,在您的解决方案中,苹果表示:“如果您在自定义视图控制器中重写此方法,请始终在实现中的某个点调用super”iPad air 1和2返回的值不正确,iPad 2和iPhone是正确的。我真的很想找到一个能在所有设备上运行的,但苹果在这里搞得一团糟(与UIDevice.current.orientation
不同,UIApplication.shared.statusBarOrientation
在初始加载时可用,而不仅仅是在屏幕旋转后。不适用于iOS 9和10 iPad,只有初始值正确,以下所有值都是相反方向。@Steven.B Hmmm…适用于我的iPad Air、iPad 3和simulatoiOS 9下的r。也与beta测试人员一起工作。可能您还使用了其他影响此功能的代码。此代码可能仅在UIViewcontroller中使用时有效,我尝试在自定义UIView类中获取方向和边界,但当方向正确于帧或边界时,我测试的几乎每个设备都返回不同的值ds仍然是错误的。完美的答案!谢谢你,但是为什么你写它两次而不是@objc class var isLandscape:Bool{return!isPortrait}我没有得到一些重要的东西?;)哇,它工作得很好,因为我不会。。多谢各位
print(UIApplication.shared.statusBarOrientation.isPortrait)
if UIApplication.shared.windows.first?.
windowScene?.interfaceOrientation.isPortrait ?? true {
print("Portrait")
} else {
print("Landscape")
}
// app start
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let orientation = self.view.window?.windowScene?.interfaceOrientation {
let landscape = orientation == .landscapeLeft || orientation == .landscapeRight
}
}
// on rotation
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
let landscape = UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight
}
struct Orientation {
/// true - if landscape orientation, false - else
static var isLandscape: Bool {
orientation?.isLandscape ?? window?.windowScene?.interfaceOrientation.isLandscape ?? false
}
/// true - if portrait orientation, false - else
static var isPortrait: Bool {
orientation?.isPortrait ?? (window?.windowScene?.interfaceOrientation.isPortrait ?? false)
}
/// true - if flat orientation, false - else
static var isFlat: Bool {
orientation?.isFlat ?? false
}
/// valid orientation or nil
static var orientation: UIDeviceOrientation? {
UIDevice.current.orientation.isValidInterfaceOrientation ? UIDevice.current.orientation : nil
}
/// Current window (for both SwiftUI and storyboard based app)
static var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return UIApplication.shared.windows.first
}
return window
}
}
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
layoutAll()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
print("viewWillTransition")
layoutAll()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
print("traitCollectionDidChange")
layoutAll()
}
/// Layout content depending on the orientation
private func layoutAll() {
// Layout as you need
print("layoutAll: isLandscape=\(Orientation.isLandscape), isPortrait=\(Orientation.isPortrait), traitCollection=\(traitCollection)")
}
}