When iOS 7 was announced at WWDC in 2013, there were an incredible amount of new APIs that caught my eye. Watching one of the developer sessions from my couch in Ohio a few hours after it took place, I stumbled upon session 218: Custom Transitions Using View Controllers.
This session contained a lot of confusing information about an incredibly exciting new API. I say "incredibly exciting" because graphics and user interaction on iOS are what really get me going. I love exploring and discovering new ways to delight my users.
The core functionality of this new API uses the protocol
This is how Apple describes the new API:
If you're confused, don't worry, so was I. This screen cap just about sums up the entire session 218 video as well as the sample code.
I was really hoping we'd get to see some examples of how Apple created their custom transitions, but the only sample provided performs a simple transition using
UICollectionViewCell animations, which is a little different than the
UIViewController transitions they demo in the session.
I'll attempt to explain how
UIViewControllerAnimatedTransitioning works as briefly as I can.
You are currently looking at view controller A and want to present view controller B.
You initialize a transition and are given a container view that facilitates the animation of your transition.
Add view controller B's view to the container.
Perform an animation on the views of view controllers A and B (not on the container).
Afterwards you're left with view controller B presented, and, by calling
animationEnded:, the presentation is completed.
Both guides are great and do a good job at explaining how to create your own custom UIViewController custom transitions from scratch. However, both fail to explain how to implement proper orientation support.
I started experimenting and quickly found what I thought to be a bug. On July 15th I filed my first bug report with Apple (#14444833, thanks for those who resubmitted). I also created a thread on the dev forums that got some attention.
No one ever got an official answer.
After some digging, I found that the container view's frame is always laid out in portrait, even if the device is in landscape.
The frame layout was likely our biggest source of confusion.
It took a lot of tinkering, but I finally found a useful solution. Even though the frame of the container view is stuck in portrait, I found that the bounds of the container view is always corrected for device orientation.
I'm not entirely sure that this is intended, but since the container view should be agnostic of your view controller hierarchy, it shouldn't necessarily adjust for orientation.
From the frame documentation:
The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.
From the bounds documentation:
The bounds rectangle, which describes the view’s location and size in its own coordinate system.
The view controller transition API is simply too vague in its current form. More sample code and documentation really needs to be provided. But for now, if you're going to use custom view controller transitions, make sure to adjust your new views with the bounds of the container.
I've setup a Github project with examples using code, NIBs, and Storyboards. Please feel free to use the code from my transition controller as a starting point. Hopefully this will provide a good starting point to perform awesome, oriented animations.Tweet