Good day, friends!
I failed trying to animate views that were set in IB from code. App crashes with following reason:
The view hierarchy is not prepared for the constraint...
I saw some similar questions here and the reason was always that the view which was created programmatically, is not yet added to superview. But I created all views in IB!
The console also says:
View not found in container hierarchy: (here goes it's superview)
It doesn't make any sense to me because in fact it is a subview of appropriate superview, and xcode knows it - it prints view hierarchy right away and it fits.
What could the reason? Thank you!
Edit: code I use:
- (void)setEditingConstraintsForView:(UIView *)view
{
// Pin given view to top, fix it height
NSDictionary *givenView = @{@"view":view};
view.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:givenView];
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view(height)]" options:0 metrics:@{@"height":@(viewHeight)} views:givenView];
[self.animatedVIew addSubview:view];
for (NSArray *constraints in @[horizontalConstraints, verticalConstraints]) {
[view addConstraints:constraints];
}
}
Also I delete all constraints that I set in IB before installing new:
- (NSDictionary *)constraintsFromIB
{
if (!_constraintsFromIB) {
_constraintsFromIB = @{@"view1":self.view1.referencingConstraintsInSuperviews,
@"view2":self.view2.referencingConstraintsInSuperviews,
@"view3":self.view3.referencingConstraintsInSuperviews };
}
return _constraintsFromIB;
}
And then:
- (void)updateViewConstraints
{
[super updateViewConstraints];
// clear all constraints
for (NSString *viewName in self.constraintsFromIB.allKeys) {
for (NSLayoutConstraint *constraint in self.constraintsFromIB[viewName]) {
[constraint remove];
}
} }
UPDATE 2: Method I use invoke change: when user touches the view, this one is called:
- (void)animateConstraintsForState:(LDYEditingLabel)state
{
self.editingLabel = state;
[UIView animateWithDuration:0.3 animations:^{
[self updateViewConstraints];
[self.view layoutIfNeeded];
}];
}
Later in updateViewConstraints:
there is a code that triggers my method setEditingConstraintsForView:(UIView *)view
Select the height constraint from the Interface builder and take an outlet of it. So, when you want to change the height of the view you can use the below code. Method updateConstraints() is an instance method of UIView . It is helpful when you are setting the constraints programmatically.
if you use IB to create constrains you can add constrains as outlet.
You then update the constrain and call [self updateViewConstraints]; in the animation block
If it were me, I'd wire the constraints to IBOutlets and just modify the existing constraints. It would probably end up being easier than adding and removing them programmatically.
You may also need to call setNeedsLayout
after you've modified the constraints.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With