我认为以这种方式保留Storyboard NSLayoutConstraint IBOutlet的值的最佳方法是什么,以使此修改保留方向/大小类更改。

我已经在情节提要约束中定义了某些尺寸类ex的Installed属性打开。常规/紧凑型,并针对其他尺寸类别(如紧凑/常规)关闭。

我可以通过viewDidAppear()中的IBOutlet从代码中修改此约束的值,但是它只能在旋转设备之前起作用。
卸载设备旋转约束后,将再次使用旧的情节提要值重新安装(或者如果在代码中停用,则再次重新激活)。

因此,我尝试在traitCollactionDidChange()方法中添加其他修改。但是它不起作用,它在设置Stroyboard约束值之前被调用!因此,我的修改被情节提要中定义的值覆盖。

然后,我尝试了viewDidLayoutSubviews()(UIViewController)或layoutSubviews()(UIView)。在简单视图的情况下,它似乎可以工作,但是如果我添加了更多视图修改,则计算不可行,这将使我无法适应旋转。

因此,作为最后的手段,我向traitCollectionDidChange()添加了具有1秒延迟的Timer.scheduledTimer()似乎可以正常工作,但似乎也很奇怪。如果故事板在这一秒后设置约束值,那苹果可能会在下一版本的Swift / iOS中进行一些更改。我可以中继这种黑客吗?

我的代码:

 override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        if UIDevice.current.userInterfaceIdiom == .pad  {
            bottomConstraint.isActive = false
        } else if traitCollection.sizeClasses == (.regular, .compact) {
            iphoneLeadingSpacerProportionalWidth = leadingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
            iphoneTrailingSpacerProportionaWidth = trailingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
        }
    }

    private var iphoneLeadingSpacerProportionalWidth : NSLayoutConstraint? = nil
    private var iphoneTrailingSpacerProportionaWidth : NSLayoutConstraint? = nil

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        if let leadingConstraint = iphoneLeadingSpacerProportionalWidth,
            let trailingConstraint = iphoneTrailingSpacerProportionaWidth {
            NSLayoutConstraint.deactivate([leadingConstraint, trailingConstraint])
        }

        Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (timer) in
            if UIDevice.current.userInterfaceIdiom == .pad  {
                self.bottomConstraint.isActive = false
            } else if self.traitCollection.sizeClasses == (.regular, .compact) {
                self.iphoneLeadingSpacerProportionalWidth = self.leadingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
                self.iphoneTrailingSpacerProportionaWidth = self.trailingSpacerProportionalWidth.setMultiplier(multiplier: 0.1)
            }
        }
    }

重要!这个 setMultiplier()使用了我发现的一些扩展名,因此,如果我将设置约束,请不要对其进行替换。constant = toSomeValue

最佳答案

您可以在情节提要板本身中为不同大小的类设置不同的值。见附件。

ios - AutoLayout Storyboard 约束-如何在代码中进行修改以在方向更改中使用此修改-LMLPHP

ios - AutoLayout Storyboard 约束-如何在代码中进行修改以在方向更改中使用此修改-LMLPHP

如果您仍然想通过代码进行更新。您应该使用它来检测方向。

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    if UIDevice.current.orientation.isLandscape {
        print("Landscape")
    } else {
        print("Portrait")
    }
}

关于ios - AutoLayout Storyboard 约束-如何在代码中进行修改以在方向更改中使用此修改,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52790050/

10-15 14:11