How to Create an iOS Book Open Animation: Part 2
Learn how to create an iOS book open animation including page flips, with custom collection views layout and transitions. By Vincent Ngo.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Create an iOS Book Open Animation: Part 2
30 mins
- Getting Started
- Creating your Custom Navigation Controller
- Creating the Custom Transition
- Setting up Your Transition
- Creating the Push Transition
- State 1 – Closed Book
- State 2 – Opened Book
- Implementing the Book Opening Transition
- Applying the Push Transition to the Navigation Controller
- Implementing the Pop Helper Methods
- Applying the Pop Transition to the Navigation Controller
- Creating an Interactive Navigation Controller
- Where To Go From Here?
Welcome back to our iOS book open animation tutorial series!
In the first part of this tutorial series, you learned how to create two custom collection view layouts and applied shadow layers to the book’s pages to create depth and realism in your app.
In this final part, you’ll learn to create custom navigation transitions and apply interactive gestures to open a book with a pinch gesture.
Note: Full credit goes to Attila Hegedüs for creating this awesome sample project.
Note: Full credit goes to Attila Hegedüs for creating this awesome sample project.
Getting Started
The tutorial picks up from Part 1. If you didn’t work through the last part, or want to start afresh, simply download the completed sample project from the previous tutorial.
Open up the project in Xcode. Right now, when you select a book to read the open pages simply slide in from the right. This is the default transition behavior for a UINavigationController. But by the end of this tutorial, your custom transition will look like the following:
The custom transition will animate the book smoothly between the closed and opened states in a natural manner that users will love.
Time to get started!
Creating your Custom Navigation Controller
To create a custom transition on a push or pop you must create a custom navigation controller and implement the UINavigationControllerDelegate
protocol.
Right-click (or Ctrl-click) on the App group and click New File. Select the iOS\Source\Cocoa Touch Class template and name the new file CustomNavigationController. Make sure it’s a subclass of UINavigationController and set the language to Swift. Click Next and then Create.
Open CustomNavigationController.swift and replace its contents with the following:
import UIKit
class CustomNavigationController: UINavigationController, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
//1
delegate = self
}
//2
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation == .Push {
return nil
}
if operation == .Pop {
return nil
}
return nil
}
}
Here’s what you’re doing in the code above:
- In
viewDidLoad
you set the navigation controller as its own delegate. -
navigationController(_:animationControllerForOperation:fromViewController:toViewController:)
is one of the methods you can implement forUINavigationControllerDelegate
. This method executes each time you push or pop between view controllers, and you control which animated transition you return from this method. The code currently returnsnil
which defaults to the standard transition. You’ll replace it with your own custom transition object shortly.
Now that you have your custom navigation controller set up, it’s time to replace the default navigation controller in storyboard.
Open Main.storyboard and click Navigation Controller in the storyboard’s view hierarchy on the left. Next, click the Identity Inspector and under Custom Class, change UINavigationController to CustomNavigationController, as shown below:
Build and run to ensure everything still works; nothing will have changed since you’re returning nil
in your delegate method, which defaults to the navigation controller’s standard transition.
Creating the Custom Transition
Time for the fun part — building your custom transition object! :]
With a custom transition object, the class you create must conform to the UIViewControllerAnimatedTransitioning protocol, and in particular, the methods below:
- transitionDuration: Required. Returns the duration of the animation and synchronizes interactive transitions.
- animateTransition: Required. Provides the to and from controllers you’re transitioning between. Most of the heavy lifting will be done in this method.
- animationEnded: Optional. Informs you when the transition has finished. You can perform any required cleanup in this method.
Setting up Your Transition
Right-click (or Ctrl-click) on the App group and click New File. Select the iOS\Source\Cocoa Touch Class template and name the new file BookOpeningTransition. Make sure it’s a subclass of NSObject and set the language to Swift. Click Next and then Create.
Open BookOpeningTransition.swift and replace its contents with the following:
import UIKit
//1
class BookOpeningTransition: NSObject, UIViewControllerAnimatedTransitioning {
// MARK: Stored properties
var transforms = [UICollectionViewCell: CATransform3D]() //2
var toViewBackgroundColor: UIColor? //3
var isPush = true //4
//5
// MARK: UIViewControllerAnimatedTransitioning
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
return 1
}
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
}
}
Taking each commented section in turn:
-
BookOpeningTransition
implements the required methods for theUIViewControllerAnimatedTransitioning
protocol. - The dictionary
transforms
stores key value pairs, where the key is aUICollectionViewCell
and the value is of typeCATransform3D
. This dictionary tracks each cell’s page transform when the book is open. - This defines the color you transition to, which helps the fade look much cleaner.
- The boolean
isPush
determines whether the transition is a push, or a pop, - Here you add the required methods for
UIViewControllerAnimatedTransitioning
to avoid build errors; you’ll implement these methods shortly.
Now that you have your variables set up, it’s time to implement the protocol methods.
Replace the contents of transitionDuration(_:)
with the following:
if isPush {
return 1
} else {
return 1
}
transitionDuration(_:)
returns the duration of the transition animation. In this case, you want it to take 1 second on either a push or a pop. Writing the method this way lets you easily change the timing of the push or pop.
Next, you need to implement the second required protocol method — animateTransition
— where the magic will happen! :] You’ll implement this in two parts:
- Implement the helper methods to set up
animateTransition
for a push. - Implement the helper methods to set up
animateTransition
for a pop.
Creating the Push Transition
Imagine yourself opening a book in real life:
Although it looks complicated, you only need to consider the two states of your animation and let UIView
‘s method animateWithDuration
handle the animation between the following two states:
- Stage 1 is when the book is closed.
- Stage 2 is when the book is open; this is essentially the transform you created in Part 1 of this tutorial.
First, you’ll implement some helper methods to handle the two states before you implement the animateTransition(_:)
protocol method.
Still in BookOpeningTransition.swift, add the following code to the end of the class:
// MARK: Helper Methods
func makePerspectiveTransform() -> CATransform3D {
var transform = CATransform3DIdentity
transform.m34 = 1.0 / -2000
return transform
}
This code returns a transform and adds perspective in the z-axis. You’ll use this later to help transform your views during the animation.