如何在addSubview之后添加约束,以便子视图使用superview调整大小

eri*_*icg 8 macos xcode cocoa autolayout swift

我有一个示例项目,在这里演示了这个问题

https://github.com/ericgorr/autolayout_with_addsubview.git

我有一个名为CalcView的视图,我想以编程方式将其作为子视图添加到应用程序主窗口上的视图中.当我调整窗口大小时,我想要调整CalcView的大小.

在MainWindowController的windowDidLoad中,我通过执行以下操作添加子视图:

let calcViewController  = ELIZCalcView()
let calcView            = calcViewController.view

calcContentView?.addSubview( calcViewController.view )
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下方式添加约束:

let bindings            = [ "calcView": calcView ]

let horizontalContraint:[AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat( "H:|[calcView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: bindings )
let verticalContraint:[AnyObject]   = NSLayoutConstraint.constraintsWithVisualFormat( "V:|[calcView]|", options: NSLayoutFormatOptions(0), metrics: nil, views: bindings )

calcContentView?.addConstraints( horizontalContraint )
calcContentView?.addConstraints( verticalContraint )
Run Code Online (Sandbox Code Playgroud)

现在,对于知道如何正确解释该代码的人来说,很明显它不会起作用.在我运行我的应用程序后,我根本无法调整窗口大小.此外,我在控制台中看到以下错误消息:

2015-07-04 16:04:45.019 aocsCalc[5797:3526462] Unable to simultaneously satisfy constraints: (
    "<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00]   (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00]   (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500 )>" )

Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00]   (Names: '|':aocsCalc.ELIZHighlightView:0x608000120500 )>

Set the NSUserDefault NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints to YES to have -[NSWindow visualizeConstraints:] automatically called when this happens.  And/or, break on objc_exception_throw to catch this in the debugger.
Run Code Online (Sandbox Code Playgroud)

如果我删除垂直约束,错误消息就会消失,我可以垂直调整窗口大小.

那么,我需要做什么简单的事情呢?CalcView与窗口一起调整大小?

NKo*_*kov 15

在将calcView添加为子视图之前,请尝试插入以下代码行:

calcView.translatesAutoresizingMaskIntoConstraints = false
Run Code Online (Sandbox Code Playgroud)

这应该可以解决您的问题.

默认情况下,在UIView/NSView上,此属性设置为YES/true,并根据自动调整掩码创建自己的约束集.这些自动制约的约束与您在代码中创建的约束冲突.

它在错误描述中也清楚地说明了这一点.在第2行和第3行,它向您显示关于一个视图NSView:0x600000120f00有两组垂直约束 - 它们似乎是您的calcView.

<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00] 
<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00]
Run Code Online (Sandbox Code Playgroud)

它们都是垂直的.首先想要查看超级视图的顶部没有边距.第二个(自动创建)想要以小的边距捕捉它,可能取自它在Interface Builder中的布局.

UPDATE

创建一个新的Cocoa Application项目并粘贴以下代码:

override func viewDidLoad() {
    super.viewDidLoad()

    let view = NSView()
    view.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(view)

    //Making it red just to see a little better. Ignore this two lines.
    view.wantsLayer = true
    view.layer?.backgroundColor = CGColorCreateGenericRGB(1, 0, 0, 1)
    //-----------------------------------------------------------------

    let views = ["view" : view]
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|-[view]-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views))
    self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[view]-|", options: nil, metrics: nil, views: views))

}
Run Code Online (Sandbox Code Playgroud)

新创建的NSView被捕捉到View Controllers主视图,带有标准边距(8个点,在可视格式字符串中描述为" - "),并使用主视图调整大小(参见图片).一点点提示 - 您不必以可视格式指定"H:",只需"V:".它默认是水平的.

这应该可以让您了解如何以编程方式添加约束.代码可能不是最优的,我在Obj-C中编码并且知道很少的Swift.

我已经下载了你的项目.错误可能位于复杂的视图层次结构和xib操作中.但这是另一个故事.还要小心滚动视图,它们在autolayout方面有点棘手,你可以在SO上找到很多关于它的报道.快乐编码:)

在此输入图像描述 在此输入图像描述