自动布局程序大小问题:无法调整 Superview 的大小

Autolayout Programatic Sizing Woes: Cannot Resize Superview

如果我在 IB 中定义约束,我仍然可以调整包含子视图的 window 的大小。


所有其他约束都相同,但分别是左、右和下。


当我尝试在代码中执行此操作时,我无法再在运行时手动调整超级视图 (NSWindow) 的大小,也无法将其最大化:

class ViewController: NSViewController {

    @IBOutlet var box : NSBox!

    func matchAttribute(attribute: NSLayoutAttribute, view: NSView, superview: NSView) {
        var constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: NSLayoutRelation.Equal, toItem: superview, attribute: attribute, multiplier: 1, constant: 0)
        constraint.priority = 1000
        superview.addConstraint(constraint)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        self.matchAttribute(NSLayoutAttribute.Top, view: self.box, superview: self.box.superview!)
        self.matchAttribute(NSLayoutAttribute.Trailing, view: self.box, superview: self.box.superview!)
        self.matchAttribute(NSLayoutAttribute.Leading, view: self.box, superview: self.box.superview!)
        self.matchAttribute(NSLayoutAttribute.Bottom, view: self.box, superview: self.box.superview!)
    }
}

我必须怎么做才能以编程方式获得相同的自动布局行为?

因为您没有在 Interface Builder 中向您的框添加任何约束,所以在加载时它被认为具有不明确的布局。为了消除这种歧义,Cocoa 自动添加了一些约束:

override func viewDidLoad() {
    super.viewDidLoad()

    println(view.constraints)
    //-> <NSIBPrototypingLayoutConstraint:0x600000082e40 'IB auto generated at build time for view with fixed frame' H:|-(0)-[NSBox:0x100716940'This Is A Box'](LTR)   (Names: '|':AutoStack.PPView:0x100516120 )>
    //-> <NSIBPrototypingLayoutConstraint:0x600000082ee0 'IB auto generated at build time for view with fixed frame' V:|-(0)-[NSBox:0x100716940'This Is A Box']   (Names: '|':AutoStack.PPView:0x100516120 )>
    //-> <NSIBPrototypingLayoutConstraint:0x600000082f80 'IB auto generated at build time for view with fixed frame' H:[NSBox:0x100716940'This Is A Box'(480)]>
    //-> <NSIBPrototypingLayoutConstraint:0x600000083020 'IB auto generated at build time for view with fixed frame' V:[NSBox:0x100716940'This Is A Box'(270)]>
}

您会注意到最后两个约束的组合效果是固定框的宽度和高度 - 这就是为什么您不能调整 window 的大小,因为这样做会违反这些约束。

要获得您想要的效果,您首先需要删除这些自动生成的约束:

override func viewDidLoad() {
    super.viewDidLoad()

    view.removeConstraints(view.constraints)
    // Forbid Cocoa from automatically adding its own constraints to this view 
    view.translatesAutoresizingMaskIntoConstraints = false

    // Note that in your implementation you are needlessly typing <self>
    matchAttribute(NSLayoutAttribute.Top, view: box, superview: box.superview!)
    matchAttribute(NSLayoutAttribute.Trailing, view: box, superview: box.superview!)
    matchAttribute(NSLayoutAttribute.Leading, view: box, superview: box.superview!)
    matchAttribute(NSLayoutAttribute.Bottom, view: box, superview: box.superview!)
}