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

Xcode 如何在addSubview之后添加约束,以便子视图随superview调整大小,xcode,macos,swift,cocoa,autolayout,Xcode,Macos,Swift,Cocoa,Autolayout,我有一个示例项目,在这里演示了这个问题 我有一个名为CalcView的视图,我想通过编程将其作为子视图添加到应用程序主窗口的视图中。调整窗口大小时,我希望调整CalcView的大小 在MainWindowController中的windowDidLoad中,我通过执行以下操作添加子视图: let calcViewController = ELIZCalcView() let calcView = calcViewController.view calcContentV

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

我有一个名为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 )
我尝试通过以下操作添加约束:

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.
2015-07-04 16:04:45.019 aocsCalc[5797:3526462]无法同时满足约束:(
"",
"" )
将尝试通过打破约束进行恢复
将NSUserDefault NSConstraintBasedLayoutVisualizationMutuallyExclusiveConstraints设置为YES,以便在发生这种情况时自动调用-[NSWindow VisualizationConstraints:]。和/或,在objc_异常_抛出时中断,以便在调试器中捕获该异常。
如果删除垂直约束,错误消息将消失,并且可以垂直调整窗口大小


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

在将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]
新创建的NSView以标准边距(8个点,在视觉格式字符串中被描述为“-”)捕捉到视图控制器主视图,并随主视图调整大小(参见图片)。一点提示-您不必在视觉格式中指定“H:”,只需指定“V:”。默认情况下,它是水平的

这将使您很好地了解如何以编程方式添加约束。代码可能不是最优的,我用Obj-C编码,对Swift知之甚少

我已经下载了你的项目。错误可能存在于复杂的视图层次结构和xib操作中。但这完全是另一回事。同样要注意滚动视图,当涉及到自动布局时,它们有点棘手,你可以在上面找到很多内容。快乐编码:)


很抱歉,我没有太多的OS X开发经验,但我认为UIView和NSView在约束方面的作用是相同的。假设NSView具有该属性。您一定键入了错误的内容。将其从函数调用更改为属性赋值可以消除编译错误,但我看到的实际行为要糟糕得多。视图在窗口上的位置不再正确。我已经更新了Git Hub项目。你原来的问题已经得到回答,所以你应该考虑给予NKorotkov荣誉。我已经下载并运行了您的更新项目,但无法真正了解问题所在。你应该明确你想要实现什么,但不能实现什么-可能在一个单独的问题中(+1,顺便说一句,发布示例项目)。@ericgorr我已经更新了我的答案。这应该足以理解如何在代码中使用autolayout。谢谢。但是,我正在寻找我在github上提供的代码的解决方案。