3

我有一个我想看起来像这样的视图:

|---------------|
|               | <- navBar
|---------------|
|               | <- topView
|---------------|
|               |
|               |
|               |
|---------------|

我想要的只是将 topView.top 粘贴到 navBar.bottom 上。我决定使用制图并实现以下代码(试图坚持使用 MVC ofc):

在我的UIViewController子类中:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    aView?.topLayoutGuide = self.topLayoutGuide // where aView is my subclass of UIView, inserted in loadView method
}

在我的UIView子类中:

var topLayoutGuide: UILayoutSupport?

override func updateConstraints() {
    var constraint = NSLayoutConstraint?()
    layout(topView) { (topView) in
        constraint = topView.top == topView.superview!.top
    }
    topView.superview!.removeConstraint(constraint!)

    layout(topView) { topView in
        topView.top == topView.superview!.top + (self.topLayoutGuide?.length ?? 0)
        topView.height == 67
        topView.left == topView.superview!.left
        topView.width == topView.superview!.width
    }

    super.updateConstraints()
}

问题是我收到以下日志,但我不知道如何修复它:

Unable to simultaneously satisfy constraints.
[...]
(
    "<NSLayoutConstraint:0x7fe6a64e4800 V:|-(64)-[UIView:0x7fe6a6505d80]   (Names: '|':MyApp.MyView:0x7fe6a360d4c0 )>",
    "<NSLayoutConstraint:0x7fe6a3538a80 V:|-(0)-[UIView:0x7fe6a6505d80]   (Names: '|':MyApp.MyView:0x7fe6a360d4c0 )>"
)

看来我需要一些帮助。如何正确地做到这一点?我不想在其中实施约束,UIViewController也不想使用Storyboards.

谢谢你的帮助!

4

2 回答 2

3

一种解决方案:创建对该特定的引用NSLayoutConstraint,并更新其constant

var topLayoutConstraint: NSLayoutConstraint!

override func updateConstraints() { 
    layout(topView) { topView in
        topLayoutConstraint = topView.top == topView.superview!.top
        topView.height == 67
        topView.left == topView.superview!.left
        topView.width == topView.superview!.width
    }

    super.updateConstraints()
}

...然后,您可以像这样调整该 NSLayoutConstraint 的常量:

topLayoutConstraint.constant = 50

剩下的唯一问题是 - 你什么时候更新topLayoutConstraint?一种解决方案是创建一个协议MyViewInterface

protocol MyViewInterface: class {
    var topLayoutGuideLength: CGFloat { get set }
}

然后,在我们的 中UIView,当该topLayoutGuideLength属性发生变化时,我们调整constant我们的NSLayoutConstraint

public class MyView: UIView, MyViewInterface {
    public var topLayoutGuideLength: CGFloat = 0 {
        didSet {
            topLayoutConstraint.constant = topLayoutGuideLength
        }
    }
}

最后,在我们的UIViewController(我们topLayoutGuide生活的地方):

public class myViewController: UIViewController {

    private var myView: MyView

    // ...

    public override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        myView.topLayoutGuideLength = topLayoutGuide.length
    }
}

最终结果?每当viewDidLayoutSubviews()在 our 上触发时UIViewController,我们myViewtopLayoutGuideLength属性就会更新,这会触发 that 的topLayoutConstraint更改constant

于 2015-07-22T17:42:31.887 回答
1

另一个缺乏制图文件......

我遇到了topLayoutGuideCartography属性bottomLayoutGuideCartography作为UIViewController制图的扩展。使用它们可以在不覆盖的情况下为您提供所需的输出viewDidLayoutSubviews

您可以简单地使用此属性来锚定视图的顶部。

override func updateConstraints() { 
    layout(topView) { topView in
       topView.top == topLayoutGuideCartography
       topView.height == 67
       topView.left == topView.superview!.left
       topView.width == topView.superview!.width
    }

    super.updateConstraints()
}
于 2016-11-17T00:24:17.640 回答