Update: View Controller transitions are terribly broken in landscape. I’d advise avoiding this if you need anything other than portrait transitions.
Few will debate the divisiveness of the aesthetics of iOS 7, but what many seem to have only just started talking about is just how API rich this latest release is. I generally hesitate to write about brand new API (it’s just too hard to do it authoritatively without having spent real time with it) but the new flexibility in view controller transition animations is somewhat near and dear to Joel and I.
If you’ve spent any time in the past writing code to do custom animations between view controllers, you likely already know how challenging it was to keep code cleanly isolated; and even when proper encapsulation achieved, there was the tendency towards whole separate tracks of willDisplay/didDisplay logic in parallel with the standard
UIViewController flow. The encapsulation of the new
UIViewControllerAnimatedTransitioning mechanism is so clean and pluggable that I hope (and expect) to see transition animators popping up all over GitHub. We’d like to help kick off this trend. (skip right to the code)
If you haven’t read up on the new transition API, I recommend first taking a look at Ash Furrow‘s recent post, Custom UIViewController Transitions, it’s a fantastic nuts and bolts guide to quickly getting moving with custom transitions.
SMLBookshelfTransitionAnimator provides an easy to use “bookshelf” animation between two view controllers, similar to the well known transition in iBooks. The bulk of the animation code was written by Joel, originally as part of a redesign of my very first (and very old) App Store app, Peg Jump. Truth be told, I’m not even sure this rotating 3D box is a style we’ll see much of in the post iOS 7 world, but it still fits in nicely with a heavily stylized game.
Admittedly, the Core Graphics animation to achieve this effect isn’t the most complex animation in the world. All the relevant views are added to a CATransformLayer with transforms applied such that they are positioned in the form of a “box”, the transform layer is then animated 180° in 3D space. The original code was not terribly elegant, it ripped the backing
CALayer out of the
UIView for the front and back controllers. This animated superbly, but required some terribly ugly post-animation cleanup. Fortunately, iOS 7 provides some great new view hierarchy rendering API and SMLBookshelfTransitionAnimator uses these to provide the textures for the various sides of the animated bookshelf; no more view hierarchy patching necessary.
There’s some boilerplate setup required to get the transition animator passed into UIKit (read Ash Furrow’s blog post if you aren’t familiar), but setting up the animator couldn’t be simpler. SMLBookshelfTransitionAnimator provides sensible defaults, you really only need to provide it with views for the left and right sides.
SMLBookshelfTransitionAnimator *animator = [[SMLBookshelfTransitionAnimator alloc] init]; animator.leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"left.jpg"]]; animator.rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"right.jpg"]]; animator.dismissing = YES; // Required to automatically handle proper side view presentation
Options, we got em
SMLBookshelfTransitionAnimator allows customization of it’s duration, depth, perspective and rotation direction. Because we often create one off animator instances for presenting and dismissing view controllers, it also provides a couple of conveniences for automatically swapping the left and right sides to help aid in the appearance of a seamless, stateful, 3D transition.Tweet