使用viewWillTransitionToSize检测方向更改

时间:2017-01-31 20:56:06

标签: swift xcode

我已阅读过有关didRotate的帖子(来自fromInterfaceOrientation已弃用,并建议使用viewWillTransitionToSize。

但每当我尝试使用此功能时,例如

 override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.currentDevice().orientation.isLandscape.boolValue {
        print("Landscape")

    } else {

        imageView.image = UIImage(named: const)
    }

我收到一条错误,指出Method不会覆盖其超类的任何方法。 我试图在视图控制器及其视图中使用该功能,但无济于事。

1 个答案:

答案 0 :(得分:1)

如果您使用的是Swift 3,则签名是(对于UIViewController):

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
}

看看是否有帮助。

旋转后的尺寸应为willWillLayoutSubviews()viewDidLayoutSubviews()的替代方法。(我使用前者。)注意:两者都可以在一次旋转中多次调用。这是我的代码....

查看控制器:

var initialOrientation = true
var isInPortrait = false

override func viewWillLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if initialOrientation {
        initialOrientation = false
        if view.frame.width > view.frame.height {
            isInPortrait = false
        } else {
            isInPortrait = true
        }
        // call initial layout, isInPortrait is set
    } else {
        if view.orientationHasChanged(&isInPortrait) {
            // orientation has changed, isInPortrait is set
        }
    }
}

UIView扩展名:

extension UIView {
    public func orientationHasChanged(_ isInPortrait:inout Bool) -> Bool {
        if self.frame.width > self.frame.height {
            if isInPortrait {
                isInPortrait = false
                return true
            }
        } else {
            if !isInPortrait {
                isInPortrait = true
                return true
            }
        }
        return false
    }
}

修改

16个月后,我被问到是否包含了拼写错误 - 应该是viewWillLayoutSubviews还是viewDidLayoutSubviews。完整的答案是"它取决于"。

  • 此问题的基线是关于使用viewWillTransitionToSize的弱点,即如果您定位的是iPad设备,则的尺寸等级不会更改。 (另请注意覆盖的 Will 部分 - 在方向更改之前触发

  • 根据我的经验,没有"保证" viewWillLayoutSubviews viewDidLayoutSubviews只会被调用一次。但是我多年来的测试结果viewDidLayoutSubviews更有可能被调用一次。

  • 此外,在视图控制器生命周期中,viewDidLoad 触发*至少两次调用viewWillLayoutSubviews,初始调用的帧数为{{1 }}

因此,如果您需要知道 autolayout 约束激活/停用的方向更改,CGRect.zero将正常工作。但是,如果您希望操纵子视图帧,viewWillLayoutSubviews是适合的事情。

我的最新项目涉及viewDidLayoutSubviews,它使用自动布局在两个方向上尽可能大。 UIImageViewcontentMode,因此图片本身会在方向更改时自动调整大小。用户可以使用子视图来构建"一个面具(移动和调整大小),所以自动布局在这里不起作用。更多,我需要让这个面具受到限制"到实际的图像。

所以我需要"手动"通过使用两者"将"来调整/重新设置掩码帧。和"做了#34;方向改变的部分。这是我现在使用的代码。 scaleAspectFit扩展程序仍然相同,更改仅在UIView

UIViewController