xcode 如何在 addSubview 之后添加约束,以便子视图随父视图调整大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31224953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add constraints after an addSubview so the subview resizes with the superview
提问by ericg
I have a sample project which demonstrates the problem here
我有一个示例项目,它演示了这里的问题
https://github.com/ericgorr/autolayout_with_addsubview.git
https://github.com/ericgorr/autolayout_with_addsubview.git
I have a view called CalcView which I want to programmatically add as a subview to a view on the main window for the app. When I resize my window, I want CalcView to be resized.
我有一个名为 CalcView 的视图,我想以编程方式将其作为子视图添加到应用程序主窗口上的视图中。当我调整窗口大小时,我希望调整 CalcView 的大小。
In windowDidLoad in MainWindowController, I add the subview by doing:
在 MainWindowController 的 windowDidLoad 中,我通过执行以下操作添加子视图:
let calcViewController = ELIZCalcView()
let calcView = calcViewController.view
calcContentView?.addSubview( calcViewController.view )
I try to add the constraints by doing:
我尝试通过执行以下操作来添加约束:
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 )
Now, for someone who knows how to properly interpret that code, it is likely very apparent that it will not work. After I run my app, I cannot resize the window at all. Additionally, I see the following error message in the console:
现在,对于知道如何正确解释该代码的人来说,很明显它是行不通的。运行我的应用程序后,我根本无法调整窗口大小。此外,我在控制台中看到以下错误消息:
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.
If I remove the vertical constraint, the error message goes away and I can resize the window vertically.
如果我删除垂直约束,错误消息就会消失,我可以垂直调整窗口大小。
So, what simple thing do I need to do so CalcView is resized along with the window?
那么,我需要做些什么简单的事情来使 CalcView 与窗口一起调整大小?
回答by NKorotkov
Before you add your calcView as subview try inserting this line of code:
在将 calcView 添加为子视图之前,请尝试插入以下代码行:
calcView.translatesAutoresizingMaskIntoConstraints = false
This should solve your problem.
这应该可以解决您的问题。
By default on UIView/NSView this property is set to YES/true and it creates it's own set of constraints based on autoresizing mask. These auto-made constraints conflict with the ones you've created in code.
默认情况下,在 UIView/NSView 上,此属性设置为 YES/true,它会根据自动调整大小掩码创建自己的一组约束。这些自动生成的约束与您在代码中创建的约束冲突。
It clearly says so in the error description too. On lines 2 and 3 it shows you that there's 2 set of vertical constraints regarding one view - NSView:0x600000120f00
, which appears to be your calcView.
它在错误描述中也清楚地说明了这一点。在第 2 行和第 3 行,它向您显示关于一个视图 - 有 2 组垂直约束NSView:0x600000120f00
,这似乎是您的 calcView。
<NSLayoutConstraint:0x618000082440 V:|-(0)-[NSView:0x600000120f00]
<NSAutoresizingMaskLayoutConstraint:0x618000084100 h=--& v=&-- V:|-(-2)-[NSView:0x600000120f00]
They are both vertical. First one wants to snap view to the superview's top with no margin. The second one (created automatically) wants to snap it with a small margin, presumably taken from how it is layed out in Interface Builder.
它们都是垂直的。第一个想要在没有边距的情况下将视图捕捉到超级视图的顶部。第二个(自动创建的)想要用很小的边距来捕捉它,大概是从它在 Interface Builder 中的布局方式获取的。
UPDATE
更新
Create a new Cocoa Application project and paste the following code:
创建一个新的 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))
}
Newly created NSView is snapped to the View Controllers main view with standard margins (8 points, it's described as "-" in the visual format string) and is resizing with the main view (see pictures). A little tip - you don't have to specify the "H:" in the visual format, only "V:". It's horizontal by default.
新创建的 NSView 以标准边距(8 分,在视觉格式字符串中被描述为“-”)捕捉到视图控制器主视图,并随着主视图调整大小(参见图片)。小提示 - 您不必在视觉格式中指定“H:”,只需指定“V:”。默认情况下它是水平的。
This should give you a good idea of how adding constraints programmatically works. Code might not be optimal, I code in Obj-C and know very little Swift.
这应该让您很好地了解如何以编程方式添加约束。代码可能不是最优的,我用 Obj-C 编写代码并且对 Swift 知之甚少。
I've downloaded your project. Error probably lies somewhere in your complicated view hierarchy and xib manipulation. But that's a whole other story. Also be careful with scroll views, they are a bit tricky when it comes to autolayout, you can find a lot of coverage on that on SO. Happy coding :)
我已经下载了你的项目。错误可能存在于您复杂的视图层次结构和 xib 操作中。但那是另外一回事了。还要小心滚动视图,它们在自动布局方面有点棘手,你可以在 SO 上找到很多关于它的报道。快乐编码:)