我有一个展示此问题的示例项目
https://github.com/ericgorr/autolayout_with_addsubview.git
我有一个名为CalcView的视图,我想以编程方式将其作为子视图添加到应用程序主窗口的视图中。当我调整窗口大小时,我想要调整CalcView的大小。
在MainWindowController的windowDidLoad中,我通过执行以下操作添加子视图:
let calcViewController = ELIZCalcView()
let calcView = calcViewController.view
calcContentView?.addSubview( calcViewController.view )
我尝试通过执行以下操作来添加约束:
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 )
现在,对于知道如何正确解释该代码的人来说,很明显它不会起作用。在我运行我的应用程序后,我根本无法调整窗口大小。此外,我在控制台中看到以下错误消息:
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.
如果删除垂直约束,则错误消息消失,我可以垂直调整窗口大小。
那么,我需要做什么简单的事情,因此CalcView会随窗口一起调整大小?
答案 0 :(得分:15)
在将calcView添加为子视图之前,请尝试插入以下代码行:
calcView.translatesAutoresizingMaskIntoConstraints = false
这可以解决您的问题。
默认情况下,在UIView / NSView上,此属性设置为YES / true,并根据自动调整掩码创建自己的约束集。这些自动制约的约束与您在代码中创建的约束相冲突。
在错误描述中也清楚地说明了这一点。在第2行和第3行,它向您显示有关于一个视图的两组垂直约束 - NSView:0x600000120f00
,它似乎是您的calcView。
<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00]
<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00]
它们都是垂直的。首先想要查看超级视图的顶部没有边距。第二个(自动创建)想要以较小的余量捕捉它,大概取自它在Interface Builder中的布局。
<强>更新强>
创建一个新的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))
}
新创建的NSView被捕捉到具有标准边距的视图控制器主视图(8个点,在可视格式字符串中描述为“ - ”)并且正在使用主视图调整大小(参见图片)。一点点提示 - 您不必以可视格式指定“H:”,只需“V:”。它默认是水平的。
这可以让您更好地了解如何以编程方式添加约束。代码可能不是最佳的,我在Obj-C中编码并且知道很少的Swift。
我已经下载了你的项目。错误可能位于复杂的视图层次结构和xib操作中。但这是另一个故事。还要小心滚动视图,它们在autolayout方面有点棘手,你可以在SO上找到很多关于它的报道。快乐的编码:)