Wednesday, 24 June 2009

Improve iPhone flip transition performance

If you've tried animating a UIView onto the screen using UIViewAnimationTransitionFlipFromLeft or UIViewAnimationTransitionFlipFromRight you may have noticed a slight lag in the first animation. The obvious way to implement a flip transition is with code like the following:

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    [parentView addSubview:self.flipViewController.view];
    [UIView commitAnimations];
}

One explanation for the lag you sometimes see is that views are lazy loaded, and the delay is caused by the flip view being loaded. But even if you force the view to be loaded by accessing the controller's view property this lag can still manifest.

One way I found to stop this lag is to add the flip view to the parent view when the parent view loads, and set its hidden value to YES. Then when you want to animate it in, you set hidden to NO:


- (void)viewDidLoad {
    [super viewDidLoad];

    // ...

    self.flipViewController.view.hidden = YES;
    [self.view addSubview:self.flipViewController.view];
}

- (void)showFlipView {
    UIView *parentView = self.view;

    self.flipViewController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
                           forView:parentView
                             cache:YES];

    [UIView setAnimationDuration:1];
    self.flipViewController.view.hidden = NO;
    [UIView commitAnimations];
}

1 comment:

  1. Hi, I tried use this code and it gave me errors on 2nd line about .view saying:

    x error: request for member 'view' in something not a structure or union

    How should I correct it? If I overwrite it with 'window' which is my main view the animation is starting from it's flipping to the same view...
    I am confused, please help what to do

    delegate .h
    IBOutlet UIWindow *window;
    IBOutlet TwoViewAppViewController *viewController;
    IBOutlet ABVViewController *abvController;

    + property of course

    delegate .m

    - (void)flipToBackABV {
    UIView *parentView = self.view;
    ERROR POINTING TOWARDS 'VIEW'
    self.abvController.view.frame = parentView.bounds;

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
    forView:parentView
    cache:YES];

    [UIView setAnimationDuration:1];
    [parentView addSubview:self.abvController.view];
    [UIView commitAnimations];
    }

    ReplyDelete