Custom animations for unwind segues

In the previous blog post I explained how to subclass UIStoryboardSegue to create custom transitioning animations between two view controllers hosted by the same navigation controller. The custom animation is applied only to the forward transition, when navigating from the first to the second view controller. By pressing the Back button, the default pop animation kicks in, sliding the first view controller from the left edge of the screen.

In this article I demonstrate how to use the unwind segues to create the reverse animation when pressing the Back button:

reverse animation with unwind segue

The sample Xcode project is available for download on GitHub.

Create the unwind segue

Unwind segues were introduced in iOS6 to let developers customize the backward transitions between the view controller at the top of the navigation stack and a view controller at a lower level in the stack. As opposed to the standard navigation which only goes back one level, the destination view controller for an unwind segue can be at any level of the stack.

Unfortunately, creating unwind segues is not as easy as creating forward segues by Ctrl + dragging from the origin to the destination view controller in the storyboard.

First create a UIViewController subclass and assign it to the unwind segue destination view controller in the storyboard. Then implement the -handleUnwindFromDetailView: method in the custom view controller subclass. This method should be tagged as IBAction to be recognizable by Interface Builder.

The next step is to wire the Exit outlet of the origin view controller to the -handleUnwindFromDetailView: method by Ctrl + dragging from the controller outlet to the Exit outlet and selecting the method from the dropdown list:

Notice the unwind segue is created in the document outline. Select it and give it an identifier, it will be necessary in the next step:

Trigger the unwind segue

The navigation controller provides a default mechanism for the backward navigation. When a view controller is pushed on the navigation stack, the Back button is automatically added to the left of the navigation bar. By pressing it, the top view controller is popped off the stack and the application goes one level back. Additionally, a left edge pan gesture recognizer is added to the navigation controller to perform the same action.

It isn’t possible to override the Back button behavior to trigger the unwind segue, so I replaced the default button with an UIBarButtonItem instance which invokes the -performSegueWithIdentifier:sender method when pressed. This is why I previously provided an identifier to the unwind segue.

Implement the custom animation

When navigating from the grid view to the detail view, the selected thumbnail animates from its original position and size to full screen over a few milliseconds. This animation is implemented in the DetailViewController class.

The reverse animation is played when the unwind segue is performed. The detail view is resized to its original dimensions in a public DetailViewController method which is invoked inside an animation block in the overridden -segueForUnwindingToViewController: fromViewController:identifier: method. Because this method is invoked each time an unwind segue is performed between two view controllers from the navigation stack, it should be implemented in the view controller which is the parent of the two view controllers involved. In this case, the method is added to then navigation controller custom subclass.

When the animation is finished, the detail view controller is popped off of the navigation stack. Notice the animated argument of the -popToViewController:animated: method is set to NO to inhibit the default pop animation.

Conclusion

In this article I described a method to successfully implement unwind segues in iOS projects that are using storyboards. While creating unwind segues is pretty straightforward, there are specific steps that must be followed and methods to be overridden in the right places.

 

Catalin Rosioru