我有一个观点,我希望看起来像这样:
|---------------|
| | <- navBar
|---------------|
| | <- topView
|---------------|
| |
| |
| |
|---------------|
我想要的一切就是将topView.top粘贴到navBar.bottom。我决定使用Cartography并实现以下代码(试图坚持使用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
。
感谢您的帮助!
答案 0 :(得分: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
的{{1}}:
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()
时,我们的UIViewController
myView
属性就会更新,从而触发topLayoutGuideLength
&#39的更改; s topLayoutConstraint
。
答案 1 :(得分: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()
}