Reputation: 77661
I'm trying to set up a view with Auto Layout so that it animates nicely when the view changes size...
The scenario is...
I have a UIView
with a subView called animView
. animView
starts outside of the frame of the view.
As the view grows (gets taller), the animView
moves down at the same rate.
When the animView
is 10 points from the top of the view (i.e. @"V:|-10-[animView]" ) it stops and "sticks" to that point.
i.e. something like this...
Upvotes: 3
Views: 150
Reputation: 1873
This works (Dropbox share for the project):
The trick is to use an invisible UIView as a spacer object. The view you call animView is set up like this. Because I set this up partially in IB, it still raises a few issues, but you will see it works like you want.
@implementation AnimView {
UIView * _innerBox;
UIView * _spacer;
}
Then call the method - setUpEverything
from initWithCoder:
or initWithFrame:
.
- (void) setUpEverything {
// Because I set this up in IB with AutoLayout off, I think it
// still needs this. Won't work without it
self.translatesAutoresizingMaskIntoConstraints = YES;
// Otherwise you will see the box outside of animView
self.clipsToBounds = YES;
_innerBox = [[UIView alloc] init];
_innerBox.backgroundColor = [UIColor blackColor];
_spacer = [[UIView alloc] init];
_spacer.backgroundColor = [UIColor clearColor];
_innerBox.translatesAutoresizingMaskIntoConstraints = NO;
_spacer.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_innerBox];
[self addSubview:_spacer];
// Give _innerBox and _spacer some dimensions to prevent ambiguity
NSLayoutConstraint *i02 = [NSLayoutConstraint constraintWithItem:_innerBox attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:50.0f];
NSLayoutConstraint *i03 = [NSLayoutConstraint constraintWithItem:_innerBox attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:50.0f];
NSLayoutConstraint *s02 = [NSLayoutConstraint constraintWithItem:_spacer attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0f constant:50.0f];
// Center both views
NSLayoutConstraint *i05 = [NSLayoutConstraint constraintWithItem:_innerBox attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];
NSLayoutConstraint *s04 = [NSLayoutConstraint constraintWithItem:_spacer attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f];
// Set the top of _innerBox 10.0 points from the top of the superview with a low priority
NSLayoutConstraint *i01 = [NSLayoutConstraint constraintWithItem:_innerBox attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0f constant:10.0f];
i01.priority = 250;
// Pin the spacer to the bottom of _innerBox;
NSLayoutConstraint *i04 = [NSLayoutConstraint constraintWithItem:_innerBox attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_spacer attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f];
// Pin the spacer's bottom to the bottom of the superview
NSLayoutConstraint *s01 = [NSLayoutConstraint constraintWithItem:_spacer attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f];
// Stretch the spacer out as needed
NSLayoutConstraint *s03 = [NSLayoutConstraint constraintWithItem:_spacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:0 multiplier:1.0f constant:80.0f];
[self addConstraints:@[i01,i02,i03,i04,i05,s01,s02,s03,s04]];
}
Upvotes: 2