Patrick Pijnappel
Patrick Pijnappel

Reputation: 7647

Setting UIView's frame property in overlapping animation blocks causes jump

(iOS 5.1, XCode 4.4) In a project I am working on, I have two controllers that both set the frame property of the same UIView (to set size and position, respectively), in separate animation blocks that temporally overlap (the second animation block is started before the first one finishes). This seems to cause an odd jump (unanimated change) in the position of the UIView.

Minimal example to reproduce (place in viewcontroller of a new single view project (iphone), and hook up some button to the action method).

@interface ViewController ()

@property (nonatomic, strong) UIView *viewA;

@end

@implementation ViewController

- (IBAction)buttonPressed
{
    // Animate
    [UIView animateWithDuration:5 animations:^{
        self.viewA.frame = CGRectMake(0, self.viewA.frame.origin.y, 320, 200);
    }];
    [UIView animateWithDuration:5 animations:^{
        self.viewA.frame = CGRectMake(0, 200, 320, self.viewA.frame.size.height);
    }];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.viewA = [[UIView alloc] init];
    self.viewA.backgroundColor = [UIColor orangeColor];
    self.viewA.frame = CGRectMake(0, 100, 320, 100);
    [self.view addSubview:self.viewA];
}

@end

On pressing the button, you'll see the view jump about 50 pixels (half the distance it moves).

If anyone know why this is happening and/or how to address this issue, I would love to hear from you. Thank you in advance,

Patrick

Upvotes: 1

Views: 1555

Answers (2)

omz
omz

Reputation: 53551

You can use the UIViewAnimationOptionBeginFromCurrentState option to avoid the jump:

[UIView animateWithDuration:5.0 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
    self.viewA.frame = CGRectMake(0, 200, 320, self.viewA.frame.size.height);
} completion:nil];

Upvotes: 2

ohr
ohr

Reputation: 1727

That's how blocks work, you are doing both animations at the same time, try this.

[UIView animateWithDuration:5 animations:^{
    self.viewA.frame = CGRectMake(0, self.viewA.frame.origin.y, 320, 200);

 } 
completion:^(BOOL finished) {
    self.viewA.frame = CGRectMake(0, 200, 320, self.viewA.frame.size.height);
 }
];

Upvotes: 0

Related Questions