Falcoa Falcoa - 1 month ago 9
Objective-C Question

Animate view out of screen goes wrong ios

I have a view controller that contains two views. What I need is that after the view controller has been pushed, the view on top (_sidepanelview) moves to the left disappearing of the screen.

Here is what I wrote:

-(void)viewDidAppear:(BOOL)animated{
CGRect newsidepanelviewposition = _sidepanelview.frame;
newsidepanelviewposition.origin.x = -_sidepanelview.frame.size.width;


[UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
_sidepanelview.frame = newsidepanelviewposition;

} completion:^(BOOL finished) {
NSLog(@"Done!");

}];
}


The problem is that when I run the app, after the view controller been pushed, the view _sidepanelview disappears from the screen and appears again to the center of the screen coming from the right side instead of moving to the left from x=0 to x= -_sidepanelview width disappearing from the screen.

What I'm doing wrong?

Note: I did the app with auto layout unchecked and the animation worked fine, but using it with the auto layout turned on it freaks out!

Answer

As your note suggests, Auto Layout is the "culprit". Your views have constraints that are periodically enforced by the AutoLayout engine. When you alter the frame of a view, the frame changes, but not the view's layout constraints. When the next cycle of layoutSubviews occurs, your views position and size (i.e. frame) will be reset to what the constraints dictate.

If you want to include AutoLayout for that view/viewcontroller, use constraint changes to perform the animation.

The golden rule here is, setFrame is the antithesis of AutoLayout.

Sample code

-(void)viewDidAppear:(BOOL)animated {

    _sidePanelLeadingSpace.constant = -_sidepanelview.frame.size.width; // 1 

    [UIView animateWithDuration:0.5 delay:1.0 options:UIViewAnimationOptionCurveEaseIn animations:^{

        [self.view layoutIfNeeded]; // 2


    } completion:^(BOOL finished) {
        NSLog(@"Done!");

    }];
}
  1. Have a reference, _sidePanelLeadingSpace (NSLayoutConstraint), to the leading space constraint of _sidepanelview, for e.g., as an IBOutlet.
  2. Alter the constraint's constant and layout the view by calling layoutIfNeeded in an animation block
Comments