Ios 在Swift中获取设备方向

Ios 在Swift中获取设备方向,ios,swift,orientation,Ios,Swift,Orientation,我想知道如何在Swift中获取当前设备方向?我知道Objective-C有一些例子,但是我还没能在Swift中使用它 我正在尝试获取设备方向,并将其放入if语句中 这是我遇到最多问题的一条线: [[UIApplication sharedApplication] statusBarOrientation] 要获得与Objective-C代码类似的状态栏(以及UI)方向,只需: UIApplication.sharedApplication().statusBarOrientation 您还可

我想知道如何在Swift中获取当前设备方向?我知道Objective-C有一些例子,但是我还没能在Swift中使用它

我正在尝试获取设备方向,并将其放入if语句中

这是我遇到最多问题的一条线:

[[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)
和from
viewDidLoad
但它很灵活


多亏了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)")
    }
}