custom transitions

here’s the basic recipe for doing custom transition animations. (this does not include use of newer transition coordinator, just simple transitions.)

within a UIStoryboardSegue object, you are handed the two view controllers at either end of the segue.  So:

  1. you take a snapshot of your sourceViewController view, which is a UIView.
  2. add that snapshot as a subview of the destination view controller, (you may have to correct for the presence of navigation bars etc.)
  3. Push (or pop, if you’re unwinding,) the destination view.
  4. animate the snapshot where ever you like to get rid of it.
  5. then remove the snapshot from the destinationViewController view.

basically, it’s a magic trick. you’re swapping out one view controller for another that has been temporarily masked to look like the first one. and then you throw away the mask with a dramatic flourish. If you’re a fan of magic, a reasonable metaphor might be “The Pendragons” and their most famous trick.

in code, your custom UIStoryboardSegue code might look like:

-(void)perform
{
        UIView *source = [(UIViewController *)self.sourceViewController view];
        UIView *snap = [source snapshotViewAfterScreenUpdates:YES];
        [[self.destinationViewController view] addSubview:snap];
        [[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:NO];
        [UIView animateWithDuration:.5
                         animations:^{
                             //do fun animation with snap here...
                         }
                         completion:^(BOOL finished) {
                             //if you want to, you can put another UIView animate with duration here for multipart animations
                             [snap removeFromSuperview];
                         }];
}

important thing to note is the cast to (UIViewController *). Since most view controllers are custom objects, the initialization for UIStoryboardSegue defines the two as id to allow for this, so before you can send it messages, you have to tell the compiler what messages it can receive.  Alternatively, you could cast it to a id with a protocol, but you would have to make sure that you also defined any other methods that you might want to use in the protocol.  you might find it worth while to rewrite the init method of your custom segue to require a particular protocol and type as well.

Leave a Reply

Your email address will not be published. Required fields are marked *