Question

For an iOS7-only app, I have a UITableView (though it would be academic to change it to a UICollectionView if that will help) where the cells look like this:

+----------------------------------+=======+
| Label1                           | sub-  |
| Label2     Label3                | view  |
+----------------------------------+=======+

I want to transition to a second view, where the subview is zoomed out to be larger, and the label positions change, something more like this:

          +----------+
          |          |
          | subview  |
          |          |
          +----------+
             Label1
             Label2
             Label3

This is similar to the iOS7 Calendar app, where views are transitioning and animating the parts on the way. I know I'll need to implement UIViewControllerAnimatedTransitioning, but I'm conceptually having problems with how something like this would work. Do I hide the cell's subviews, replace them with the new view's subviews but in the same place, then animate those? Or is there a less convoluted way? Any sample code would be appreciated, as all of the examples I've found are not carrying subviews over from one view to the other.

ETA: The more I think about this, the more I wonder: is this better handled with a UICollectionView with a flow layout, and simply have the detail be an animated-in resizing of the cell to the full size of the screen?

Was it helpful?

Solution

The iOS7 calendar animations are, I think, done with collection view animated transition layouts, which are wonderful but not quite what you want for this situation. Also, they seem to keep you within the same view controller which may not be appropriate for a master-detail scenario as you describe above.

I've been playing with animated transitions recently and have found that the new snapshot views available in iOS7 are brilliant for this sort of thing.

I'm a huge fan of auto layout but transition animations using constraints are far too complicated. However, you can assume that at the start of a transition, your views are already laid out, so you can apply the following principles:

  • Add the incoming view to your view hierarchy
  • Create a blank canvas view on top of this
  • Create a snapshot of your outgoing view (s) and add this to the canvas
  • Create a snapshot of your incoming view (s) and add this to the canvas
  • Perform the animations between the two
  • Remove the canvas

Because the layout has already happened, you can use the center or frame properties of your existing views on these snapshots, and just animate those. It makes the code much easier to read. This is what Augie's comment above is getting at.

In your case, you can get the effect you are after by tying the various views of the selected cell to the views of the incoming controller, and animating them to their new positions.

I've made an example project with this transition, available on GitHub. The final effect looks like this:

example video

This is just a quick example to show how the animation could be performed. In production code, you'd probably make participating controllers conform to a protocol where they returned a number of views for use in transitioning rather than exposing the properties directly and tying the transition to those specific classes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top