Reputation: 629
I have 3 view hierarchies (popover, page container, pageview), pageview is placed inside the pagecontainer and pagecontainer is placed inside popover. All of them are of class UIView.
i have added a swipe gesture on the pagecontainer. when a swipe happens the page view is replaced with another page view. I am trying to get the animations right after i swipe. It begins from the current state for swipe left but it messes when i swipe right and it continues to stay messed there after for all the swipes. The animations are not consistent for some reason.
Below is the code and i tried putting the constraints inside the animation block it does not make any difference.
- (IBAction)swipeLeft:(id)sender {
if (_currentPage < [_pages count] - 1) {
UIView *currentView = _pages[_currentPage];
UIView *pageContainer = [currentView superview];
[currentView removeFromSuperview];
++_currentPage;
if (_pageControl)
_pageControl.currentPage = _currentPage;
UIView *newPage = _pages[_currentPage];
[pageContainer addSubview:newPage];
newPage.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
newPage.frame = CGRectIntegral(newPage.frame);
[pageContainer.superview layoutIfNeeded];
NSDictionary *pageviews = NSDictionaryOfVariableBindings(newPage);
if (SYSTEM_VERSION_LESS_THAN(@"7.0"))
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10.0-[newPage]-10.0-|" options:0 metrics:nil views:pageviews]];
else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0.0-[newPage]-0.0-|" options:0 metrics:nil views:pageviews]];
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0.0-[newPage]-0.0-|" options:0 metrics:nil views:pageviews]];
CGSize pageContainerSize = [pageContainer systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
pageContainer.frame = CGRectMake(pageContainer.frame.origin.x, pageContainer.frame.origin.y, pageContainerSize.width, pageContainerSize.height);
[UIView animateWithDuration:5.0
delay:0.0
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
[pageContainer.superview layoutIfNeeded];
}
completion:^(BOOL finished){
}];
UIWindow *window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[self adjustPopoverOrientationWithCurrentOrientation:window];
}
}
and...
- (IBAction)swipeRight:(id)sender {
if (_currentPage > 0) {
UIView *currentView = _pages[_currentPage];
UIView *pageContainer = [currentView superview];
[currentView removeFromSuperview];
--_currentPage;
if (_pageControl)
_pageControl.currentPage = _currentPage;
UIView *newPage = _pages[_currentPage];
[pageContainer addSubview:newPage];
newPage.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
newPage.frame = CGRectIntegral(newPage.frame);
[pageContainer.superview layoutIfNeeded];
NSDictionary *pageviews = NSDictionaryOfVariableBindings(newPage);
if (SYSTEM_VERSION_LESS_THAN(@"7.0"))
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10.0-[newPage]-10.0-|" options:0 metrics:nil views:pageviews]];
else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0.0-[newPage]-0.0-|" options:0 metrics:nil views:pageviews]];
[pageContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0.0-[newPage]-0.0-|" options:0 metrics:nil views:pageviews]];
CGSize pageContainerSize = [pageContainer systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
pageContainer.frame = CGRectMake(pageContainer.frame.origin.x, pageContainer.frame.origin.y, pageContainerSize.width, pageContainerSize.height);
[UIView animateWithDuration:5.0
delay:0.0
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
[pageContainer.superview layoutIfNeeded];
}
completion:^(BOOL finished){
}];
UIWindow *window = [[UIApplication sharedApplication].windows objectAtIndex:0];
[self adjustPopoverOrientationWithCurrentOrientation:window];
}
}
Upvotes: 1
Views: 4025
Reputation: 77661
The first rule of Auto Layout is that you can't touch the frames.
You can't change the frame, bounds or center of a view that is in an Auto Layout hierarchy.
Reading your code is a bit confusing so I'm not 100% sure what you are actually animating. But what you need to do is remove all the lines like...
pageContainer.frame = CGRectMake(pageContainer.frame.origin.x, pageContainer.frame.origin.y, pageContainerSize.width, pageContainerSize.height);
When you want to move something around the screen you need to update the constraints so that the new constraints imply the new layout.
For instance, if you want to animate the height of a view then you need to...
Keep a reference to the auto layout constraint...
@property (nonatomic, strong) NSLayoutConstraint *heightConstraint;
or...
// if you're creating the constraint in Interface Builder then CTRL drag it like any other outlet.
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *heightConstraint;
Then change the constant
property of the constraint.
// animate the height to 150.
heightConstraint.constant = 150;
and animate the layout change...
[UIView animateWithDuration:5.0
delay:0.0
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
[pageContainer.superview layoutIfNeeded];
}
completion:^(BOOL finished){
}];
Once you know which constraints need to change you can work out how best to build your constraints so that they can be animated.
EDIT
You also need to make sure you're turning off auto resizing mask translation...
[someView setTranslatesAutoresizingMaskIntoConstraints:NO];
I'd work on making the code more readable though. Possibly move stuff out to different functions to reduce code replication etc...
It's confusing to read at the moment.
Upvotes: 14