NSLayoutConstraint
我遇到了一些麻烦。
如果我尝试使用constant
方法更改setConstant:
,NSLayoutConstraint会给我一个例外。当我通过代码添加高度约束时,我只有这个问题。
首先,我得到了高度限制:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeWidth];
NSArray *filteredArray = [[self constraints] filteredArrayUsingPredicate:predicate];
return filteredArray[0];
这给了我正确的约束。我有一个NSTextField子类,这是完美的。约束在Interface Builder中设置,我可以设置和更改常量。
现在我有一个视图,我在运行时添加不同的子视图。
这些子视图位于自己的NIB中,这意味着我无法固定它们的宽度和高度。
所以我认为一旦将视图添加到superview,我就会添加约束。
这是在viewDidMoveToSuperview
执行的。
// Pin Width & Height
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:self.frame.size.width]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:self.frame.size.height]];
添加了约束,我可以用NSLog确认。
"<NSLayoutConstraint:0x100605cc0 H:[ITControlPanelChildView:0x100616eb0(269)]>",
"<NSLayoutConstraint:0x100614410 V:[ITControlPanelChildView:0x100616eb0(317)]>"
现在,最后,当我尝试使用[constraint setConstant:somethingDifferent];
更改约束时,我得到以下异常:
Unable to simultaneously satisfy constraints:
(
"<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>",
"<NSAutoresizingMaskLayoutConstraint:0x10053ff10 h=--& v=&-- V:[ITControlPanelChildView:0x10192e4f0(317)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>
这正是我试图改变的约束。 任何人都可以向我解释为什么会这样吗?
我刚刚看到NSAutoresizingMaskLayoutConstraint
被自动添加,如果您设置[self setTranslatesAutoresizingMaskIntoConstraints:NO];
,则可以停用。
如果我禁用它,它就可以。
如果我可以访问创建的NSAutoresizingMaskLayoutConstraint
,那就更好了。有谁知道这是如何工作的?
答案 0 :(得分:8)
正如您未包含的日志消息的其余部分所示,您已经获得了您不想要或不需要的自动调整约束。
添加子视图时可以删除这些内容。在上面使用的方法中,只需添加以下行:
self.translatesAutoresizingMaskIntoConstraints = NO;
虽然如果你在一个单独的笔尖中创建视图,它的大小是从哪里来的?它是否已经有尺寸限制你可以创建出口?
答案 1 :(得分:1)
我遇到了这个问题两次。
我使用了Hillegass&amp ;;的 Cocoa Programming for Mac OSX 4th Ed 中描述的技术。普雷布尔。本书建议使用NSBox作为视图容器,并使用代码将视图切换到视图容器中。本书还包括一些方便的代码,用于手动调整外部包含窗口的大小,以保存刚刚切换到的视图。
我第一次尝试他们的技术时遇到了这个例外:
2013-01-05 22:56:05.103 MyApp[17717:303] Unable to simultaneously satisfy constraints:
(
"<NSAutoresizingMaskLayoutConstraint:0x100141330 h=--& v=--& H:[NSView:0x10012fdf0(4)]>",
"<NSLayoutConstraint:0x1001316c0 H:[NSScrollView:0x100123ff0]-(NSSpace(20))-| (Names: '|':NSView:0x10012fdf0 )>",
"<NSLayoutConstraint:0x1001315d0 H:|-(NSSpace(20))-[NSScrollView:0x100123ff0] (Names: '|':NSView:0x10012fdf0 )>")
Will attempt to recover by breaking constraint
令人沮丧的是,我不得不重构UI和重建版本(基于NSDocument而不是简单的窗口)我再次遇到了同样的问题。
如果我在子视图上将translatesAutoResizingConstraints设置为NO,则它们无法正确布局。但是那些子视图很复杂,所以它不是解决方案,因为我的窗口没有布局。但这确实可以阻止异常被抛出。
如果我在基于顶级NSDocument的窗口XIB上关闭AutoLayout,那么异常也会停止抛出。但是顶级元素的布局是错误的,并且框的大小不正确。这不是那么复杂,以至于我无法手动完全解决这个问题。
奇怪的是,在我的第一个版本的UI上它没有抛出。第一个版本为顶级视图和所有子视图设置了Autolayout。
我不能为我的生活找到一个晦涩的设置,而不是另一个。我粘贴了在窗口版本中工作的完全相同的代码,用于将视图交换到基于文档的版本中,然后我通过控制检查每个设置来控制。
我第一次解决这个问题的记忆是我在XIB上关闭了AutoLayout,但现在看着它试图第二次修复,AutoLayout已经打开并且工作正常。
第一个版本有效 - 第二个版本没有。我唯一能想到的是NSDocument中的某些东西或其他东西导致了这个问题。
但是我确实找到了解决第二种情况的方法:关闭用作视图容器的NSBox的“AutoResizes子视图”复选框。
为什么UI的第一个版本不需要这个(对于那个复选框设置可以正常工作)是个谜。
无论如何 - 在此处记录,以防它帮助其他人。