Swift 4中的布局锚点

时间:2018-03-06 17:28:03

标签: ios swift autolayout layout-anchor

我正在努力更新/简化与Auto Layout和NSConstraints有关的代码,但现在似乎让我感到困惑。

我有一些Swift 3代码,只需按一下按钮即可在UIView中滑动,但是UIView受NSconstraints控制并且工作正常。 -

@IBAction func rightFlyOutButton(_ sender: Any) {
        if (rightFlyOutShowing) {
            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                leftFlyOutLeadingConstraint.constant = 25
            } else {
                leftFlyOutLeadingConstraint.constant = 15
            }
            rightFlyOutTrailingConstraint.constant = rightFlyOut.frame.width * 0.93
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        } else {
            if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
                rightFlyOutTrailingConstraint.constant = 25
            } else {
                rightFlyOutTrailingConstraint.constant = 15
            }
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        }
        rightFlyOutShowing = !rightFlyOutShowing
    }

尝试使用AutoLayout和Layout Anchors,我想到了这个 -

@IBAction func rightFlyOutButton(_ sender: Any) {
        rightFlyOut.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        rightFlyOut.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.93).isActive = true
        UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
    }

这会返回多个错误 -

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x6000000949b0 h=-&& v=-&& FasteM.UIViewX:0x7fed7140c600.width == 0.500741*UIView:0x7fed7161d760.width + 150.222   (active)>",
    "<NSLayoutConstraint:0x6000000900e0 FasteM.UIViewX:0x7fed7140c600.width == 0.93*UIView:0x7fed7161d760.width   (active)>",
    "<NSLayoutConstraint:0x600000095a90 'UIView-Encapsulated-Layout-Width' UIView:0x7fed7161d760.width == 375   (active)>"
)

我的逻辑是我将视图的右边缘锚定到超视图并指定实际视图的宽度(即超视图的93%。

我确信这是一个我错过的简单错误,但我会感谢任何指向正确的方向。

TIA

2 个答案:

答案 0 :(得分:1)

第二种方法的问题是,每次点击都会产生其他约束,这些约束会与旧的相同,所以你应该在任何地方创建这些约束,获取对它们的引用并改变它们的常量在第一个正确的方法做了

答案 1 :(得分:0)

我已经解决了这个问题,最后提出了一个有效的解决方案 -

首先创建一个变量:

var LeftFlyOutConstraint: NSLayoutConstraint?

然后在viewDidLoad()中使用以下代码:

leftFlyOut.translatesAutoresizingMaskIntoConstraints = false    
LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: 35)
    LeftFlyOutConstraint?.isActive = true

最后是按钮:

@IBAction func leftFlyOutButton(_ sender: Any) {
        if (leftFlyOutShowing) {
            LeftFlyOutConstraint?.isActive = false
                LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -40)
            LeftFlyOutConstraint?.isActive = true
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        } else {
            LeftFlyOutConstraint?.isActive = false
            LeftFlyOutConstraint = leftFlyOut.trailingAnchor.constraint(equalTo: view.leadingAnchor, constant: 35)
            LeftFlyOutConstraint?.isActive = true
            UIView.animate(withDuration: 0.4, animations: {self.view.layoutIfNeeded()})
        }
        leftFlyOutShowing = !leftFlyOutShowing
    }

并且没有报告错误。