问题
Previously in iOS6, my chat message view controller displayed and animated correctly with carefully constructed autolayout constraints in IB. Here's the current view hierarchy with the constraints removed in Xcode 5:
After upgrading to XCode 5 and iOS7, I found I needed to clear all the old constraints in order to account for the default translucent status bar, otherwise my toolbar would fall under the status bar. This happened despite calling setEdgesForExtendedLayout: with UIRectEdgeNone.
I am now attempting to create all the constraints programmatically in 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];
However, if I attempt to change the vertical space constraint between my containerView and tableContainerView, I get errors. (I'm trying to resize the tableContainerView to shrink with the appearance of the keyboard.)
[UIView animateWithDuration:0.25f
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
_constraintContainerVertSpace.constant = -keyboardHeight;
} completion:nil];
These are the constraints that fail to satisfy simultaneously:
(
"<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 in this case is _viewTableContainer. 0x140ddef0 = _viewInputContainer. 0x140dddd0 = _viewContainer.
Why is this NSIBPrototypingLayoutConstraint V:|-(460)-[UIView:0x140ddef0(_viewInputContainer)] being created by IB when I've set translatesAutoresizingMaskIntoConstraints to NO, and when I've already defined unambiguous vertical constraints between _viewInputContainer and the _tableView above it?
I've tried using Cocoa Layout in Instruments, but there's too much noise to make any sense of it.
回答1:
I had to manually remove constraints on the views in addition to using translatesAutoresizingMaskIntoConstraints.
[_viewContainer removeConstraints:_viewContainer.constraints];
[self.view removeConstraints:self.view.constraints];
After adding these changes, there were no more errors with animating.
回答2:
In order to remove the NSIBPrototypingLayoutConstraint
generated by IB, it can be solved by adding some dummy constraints on the IB, and set them remove at build time
. Then, IB
won't generate the NSIBPrototypingLayoutConstraint
for you.
回答3:
Obligatory Swift:
view.removeConstraints(view.constraints)
Alternatively, if you want to remove constraints for one particular interface item in code, you can remove them for just one object. Here are a few examples:
myTableView.removeConstraints(myTableView.constraints)
myButton.removeConstraints(myButton.constraints)
myImageView.removeConstraints(myImageView.constraints)
This can be particularly useful if you are, for example, creating a paid or free version of an app. You can do most of the interface layout in interface builder and then make tweaks to the layout in code using Visual Format Language.
来源:https://stackoverflow.com/questions/18975478/ios7-issues-with-nsibprototypinglayoutconstraint-autolayout-constraints-generate