检测屏幕方向变化(快速)

Posted

技术标签:

【中文标题】检测屏幕方向变化(快速)【英文标题】:Detect screen orientation change (swift) 【发布时间】:2020-08-09 18:37:11 【问题描述】:

如何检测屏幕方向何时在纵向和横向之间发生变化(iPhone/iPad、Swift 4)?

我正在尝试设置两个容器视图的约束,以便一个在纵向时显示在另一个之上,而在横向时并排显示(并在用户改变方向时更新)。

(我相信我可以在 Storyboard 中使用 stackview 来做到这一点 - 如果有人能告诉我如何做到这一点,我会很高兴 - 但在这种情况下我想以编程方式做到这一点。)

我认为这仅在首次加载 ViewController 时有效,但如果随后在纵向和横向之间更改方向,则不会更新约束。

class ViewController: UIViewController 

    enum Orientations 
        static let Portrait = "Portrait"
        static let Landscape = "Landscape"
        static let OtherOrientation = "OtherOrientation"
            
    var currentOrientation = Orientations.Portrait

    override func viewDidLoad() 
        super.viewDidLoad()
       
        setConstraints()
    
    

    func setConstraints() 
       // pseudocode:
       if currentOrientation == Orientations.Portrait 
           setConstraintsPortrait()
           print("Portrait")
       else if currentOrientation == Orientations.Landscape 
           setConstraintsLandscape()
           print("Landscape")
       
    


    // any help on these would also be much appreciated!
    func setConstraintsPortrait() 
        //tbd
    

    func setConstraintsLandscape() 
        //tbd
    


所以,我想我的问题是:

如何检测从纵向到横向的变化 如何应对变化 关于设置这些约束的任何其他帮助 - 我的第一个想法如下:
// Portrait
childVCTop.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
childVCTop.view.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 0).isActive = true
childVCTop.view.heightAnchor.constraint(EqualToConstant: screenHeight / 2).isActive = true
childVCTop.view.widthAnchor.constraint(EqualToConstant: screenWidth / 2).isActive = true

childVCBottom.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
childVCBottom.view.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor, constant: 0).isActive = true
childVCBottom.view.heightAnchor.constraint(EqualToConstant: screenHeight / 2).isActive = true
childVCBottom.view.widthAnchor.constraint(EqualToConstant: screenWidth / 2).isActive = true

【问题讨论】:

【参考方案1】:

如何检测从纵向到横向的变化

您可以实现 UIViewController 提供的以下方法:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) 
    super.viewWillTransition(to: size, with: coordinator)
    // here you can react to the orientation change

如何应对变化

您根据方向改变约束的想法是一个好的开始。不过,我建议使用 stackview 并更改方向轴,但这是一个疯狂的猜测。

关于设置这些约束的任何其他帮助 - 我的第一个想法如下

正如我所说,我会尝试使用 stackview 来避免代码中的约束。

【讨论】:

【参考方案2】:

使用UIApplication.didChangeStatusBarOrientationNotification 检测逻辑方向变化的最佳方法之一,例如:

override init(frame: CGRect) 
    NotificationCenter.default.addObserver(self, selector: #selector(onOrientationChange), name: UIApplication.didChangeStatusBarOrientationNotification, object: nil)
    ...


@objc func onOrientationChange(notification: Notification) 
    let isPortrait = UIApplication.shared.statusBarOrientation.isPortrait
    ...

【讨论】:

以上是关于检测屏幕方向变化(快速)的主要内容,如果未能解决你的问题,请参考以下文章

如何全局检测 swift 文件之外的设备活动方向变化?

Unity使用陀螺仪检测屏幕方向

Unity使用陀螺仪检测屏幕方向

iOS学习笔记— 屏幕旋转

如何检测 iPad 上启动屏幕动画的应用程序启动方向!

Cordova 在 Orientation="portrait" 时检测屏幕方向