以前在iOS6中,我的聊天消息视图控制器在IB中通过精心构造的自动布局约束正确显示和动画。这是在Xcode 5中删除约束的当前视图层次结构:
升级到XCode 5和iOS7之后,我发现我需要清除所有旧约束以便考虑默认的半透明状态栏,否则我的工具栏将属于状态栏。尽管使用UIRectEdgeNone调用setEdgesForExtendedLayout:发生了这种情况。
我现在正尝试在viewDidLoad中以编程方式创建所有约束:
// self.view.translatesAutoresizingMaskIntoConstraints = NO; // errors either way
NSArray *viewHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_toolbar]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_toolbar)];
[self.view addConstraints:viewHorizConstraints];
viewHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_viewContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewContainer)];
[self.view addConstraints:viewHorizConstraints];
NSArray *viewVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(20)-[_toolbar(44)]-[_viewContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_toolbar, _viewContainer)];
[self.view addConstraints:viewVertConstraints];
NSArray *tableContainerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_tableView(<=460@999)][_viewInputContainer(44)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_tableView, _viewInputContainer)];
[_viewTableContainer addConstraints:tableContainerVertConstraints];
NSArray *containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_viewTableContainer][_viewOptions]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewTableContainer, _viewOptions)];
[_viewContainer addConstraints:containerVertConstraints];
// _constraintContainerVertSpace = [NSLayoutConstraint constraintWithItem:_viewTableContainer attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:_viewContainer attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]; // same as below
containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[_viewTableContainer]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewTableContainer)];
_constraintContainerVertSpace = [containerVertConstraints lastObject];
[_viewContainer addConstraint:_constraintContainerVertSpace];
containerVertConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=0)-[_viewOptions]-(>=-216@999)-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_viewOptions)];
[_viewContainer addConstraints:containerVertConstraints];
但是,如果我尝试更改containerView和tableContainerView之间的垂直空间约束,我会收到错误。 (我正在尝试调整tableContainerView的大小以缩小键盘的外观。)
[UIView animateWithDuration:0.25f
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
_constraintContainerVertSpace.constant = -keyboardHeight;
} completion:nil];
这些是无法同时满足的约束:
(
"<NSIBPrototypingLayoutConstraint:0x140d7bb0 'IB auto generated at build time for view with fixed frame' V:|-(460)-[UIView:0x140ddef0] (Names: '|':UIView:0x140dde60 )>",
"<NSIBPrototypingLayoutConstraint:0x140d7c10 'IB auto generated at build time for view with fixed frame' V:[UIView:0x140ddef0(44)]>",
"<NSLayoutConstraint:0x14d9db30 V:[UIView:0x140ddef0]-(0)-| (Names: '|':UIView:0x140dde60 )>",
"<NSIBPrototypingLayoutConstraint:0x140e0290 'IB auto generated at build time for view with fixed frame' V:|-(0)-[UIView:0x140dde60] (Names: '|':UIView:0x140dddd0 )>",
"<NSLayoutConstraint:0x14d9df60 V:[UIView:0x140dde60]-(-216)-| (Names: '|':UIView:0x140dddd0 )>",
"<NSIBPrototypingLayoutConstraint:0x140e0830 'IB auto generated at build time for view with fixed frame' V:|-(64)-[UIView:0x140dddd0] (Names: '|':UIView:0x140e0470 )>",
"<NSLayoutConstraint:0x14d9d820 V:[UIView:0x140dddd0]-(0)-| (Names: '|':UIView:0x140e0470 )>",
"<NSAutoresizingMaskLayoutConstraint:0x1403a0b0 h=--& v=--& V:[UIView:0x140e0470(568)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x14d9db30 V:[UIView:0x140ddef0]-(0)-| (Names: '|':UIView:0x140dde60 )>
UIView:在这种情况下,0x140dde60是_viewTableContainer。 0x140ddef0 = _viewInputContainer。 0x140dddd0 = _viewContainer。
为什么这个NSIBPrototypingLayoutConstraint V:| - (460) - [UIView:0x140ddef0(_viewInputContainer)]由IB创建,当我将translateAutoresizingMaskIntoConstraints设置为NO时,以及当我已经在_viewInputContainer和_之间定义了明确的垂直约束时上面有_tableView吗?
我尝试过在仪器中使用Cocoa Layout,但是有太多的噪音让人感觉不到它。
答案 0 :(得分:18)
除了使用translatesAutoresizingMaskIntoConstraints之外,我还必须手动删除视图上的约束。
[_viewContainer removeConstraints:_viewContainer.constraints];
[self.view removeConstraints:self.view.constraints];
添加这些更改后,动画不会再出现错误。
答案 1 :(得分:10)
为了删除IB生成的NSIBPrototypingLayoutConstraint
,可以通过在IB上添加一些伪约束来解决它,并设置它们remove at build time
。然后,IB
不会为您生成NSIBPrototypingLayoutConstraint
。
答案 2 :(得分:3)
强制性斯威夫特:
view.removeConstraints(view.constraints)
或者,如果要删除代码中某个特定接口项的约束,则可以仅为一个对象删除它们。以下是一些例子:
myTableView.removeConstraints(myTableView.constraints)
myButton.removeConstraints(myButton.constraints)
myImageView.removeConstraints(myImageView.constraints)
如果您正在创建应用的付费或免费版本,则此功能特别有用。您可以在界面构建器中执行大部分界面布局,然后使用Visual Format Language对代码中的布局进行调整。