In iOS, when the navigation controller call [navigationController pushViewController: secondViewController animated: YES], the system will provide a transition animation to improve the user experience. In addition, A controller is present (or dismiss) another controller ([self presentViewController: secondViewController animated: YES Completion :NULL]) the system will also provide the corresponding transition animation. In order to make app interactive effect more exciting, iOS provides us with the implementation scheme of customized transition animation in different scenes and transition progress control by gesture. Look at this demo first.

Custom Transitions of the animation effect by implementing the UIViewControllerAnimatedTransitioning protocol instances of custom; Gesture transition progress by implementing the UIViewControllerInteractiveTransitioning protocol instances of custom. In different Transition scenarios, We through different methods of agents to the system to provide custom keep UIViewControllerAnimatedTransitioning protocol object and observe UIViewControllerInteractiveTransitioning object. Know how to define the UIViewControllerAnimatedTransitioning object and UIViewControllerInteractiveTransitioning object will give system; And know how to implement UIViewControllerInteractiveTransitioning agreement as well as the realization UIViewControllerInteractiveTransitioning, You can do your own Transition animation.


First, customize the Transitions animation usage scenario

1. A custom transition animation presented by one controller to another controller

This scenario [the call self presentViewController: secondViewController animated: YES completion: NULL] and [the self dismissViewControllerAnimated:YES completion:NULL]; When produce. The implementation steps are as follows:

(1) to be the present controller Settings have a proxy object secondViewController. TransitioningDelegate = presentationController; PresentationController UIViewControllerTransitioningDelegate instance is to realize the agreement. At the same time set up secondViewController. ModalPresentationStyle = UIModalPresentationCustom;

(2) proxy objects to achieve UIViewControllerTransitioningDelegate Method the method of agreement, the agent in return to keep UIViewControllerAnimatedTransitioning agreement and UIViewControllerInteractiveTransitioning object.

@ protocol UIViewControllerTransitioningDelegate < NSObject > @ optional / / return custom transition animations for the present. - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presentingsourceController:(UIViewController *)source; // Returns a custom transition animation for the dismiss. - (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed; // Return the transition gesture animation used for present. - (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator; // Returns the gesture-interactive transition animation used in dismiss. - (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator; // This is used when customizing PresentationController. Sample code below has the corresponding demo. - (Nullable UIPresentationController) *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presentingsourceViewController:(UIViewController *)source NS_AVAILABLE_IOS(8_0);
@end
Copy the code

2. Controller transition in UINavigationController

In this scenario [navigationController pushViewController: secondViewController animated: YES] and [self. NavigationController popViewControllerAnimated:YES]; Under production. The implementation steps are as follows:

Delegate: (1) set up the navigation controller self. NavigationController. Delegate = self;

(2) implement proxy method, return to realize UIViewControllerAnimatedTransitioning in proxy approach, and UIViewControllerInteractiveTransitioning (gesture control switch process) the object of the agreement.

// Returns the Transition animation that can be used for gesture interaction. - (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0); / / return the custom transition animations - (nullable id < UIViewControllerAnimatedTransitioning >) navigationController: (UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC NS_AVAILABLE_IOS(7_0);Copy the code

3, UITabBarController switch controller transition

By default, UITabBarController switches controllers without transition animation. Add transition effects to the switch controller by customizing the Transitiond animation. Its implementation steps are as follows:

(1) set the UITabBarController proxy object instance: self. TabBarController. Delegate = self; Proxy objects must abide by the UITabBarControllerDelegate agreement.

(2) Implement the proxy method as follows, in the proxy method to return the object that complies with the corresponding protocol.

- (nullable id <UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController interactionControllerForAnimationController: (id <UIViewControllerAnimatedTransitioning>)animationController NS_AVAILABLE_IOS(7_0);
	
- (nullable id <UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController
	            animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);
Copy the code

Second, UIViewControllerAnimatedTransitioning implementation agreement

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{ / / the length of the return to perform the conversion controller} - (void) animateTransition: (id < UIViewControllerContextTransitioning >) transitionContext {/ * * (1), Obtain the information needed to implement the animation from transitionContext such as UIView * containerView = transitionContext containerView; UIView *fromView; UIView *toView; (2), will be added to the containerView toView (all to perform the animation needs to be done in this) (3), perform the animation [UIView animateWithDuration: transitionDuration animations: ^ { } completion:^(BOOL finished) {// When the animation is finished, BOOL wasCancelled = [transitionContext transitionWasCancelled]; [transitionContext completeTransition:! wasCancelled]; } */ } }Copy the code

Three, UIViewControllerInteractiveTransitioning implementation agreement

- (void) startInteractiveTransition: (id < UIViewControllerContextTransitioning >) transitionContext {/ / do some initialization operation here [super startInteractiveTransition:transitionContext]; }Copy the code

Note: (1) agent in obtaining UIViewControllerAnimatedTransitioning method, if you have returned to realize UIViewControllerAnimatedTransitioning object of the agreement, So I’m going to use customer transition; If nil is returned, the system default is used. (2) agent in obtaining UIViewControllerInteractiveTransitioning method, if return to realize UIViewControllerInteractiveTransitioning object of the agreement, So the transition is controlled by gestures; If it returns nil, it just converts.


Use gestures to control the general flow of Transition

Add a gesture recognizer to the appropriate view and act accordingly based on the state of the gesture being listened to

switch (gestureRecognizer.state)
    {
        caseUIGestureRecognizerStateBegan: / * * listening to gestures, trigger the transition. Or call the following a method [self navigationController pushViewController: secondViewController animated: YES]; (navigation controller, or pop) or [self presentViewController: secondViewController animated: YES completion: NULL]; (presentViewController, or dismiss) or [tabBarControllersetSelectedIndex:2]; (tabBarController ) */break;
        caseUIGestureRecognizerStateChanged: / * * update progress * / [self updateInteractiveTransition: [self percentForGesture: gestureRecognizer]].break;
        case UIGestureRecognizerStateEnded:
            // Dragging has finished.
            // Complete or cancel, depending on how far we've dragged. / / is determined according to the schedule finishInteractiveTransition or cancelInteractiveTransition. If ([self percentForGesture: gestureRecognizer] > = 0.5 f) [self finishInteractiveTransition]; else [self cancelInteractiveTransition]; break; default: // Something happened. cancel the transition. [self cancelInteractiveTransition]; break; }Copy the code

Five, the Sample Code

The combination of concrete code and theory is often twice the result with half the effort. I recommend some good Sample codes to you.

  • Sample Code: Custom View Controller Presentations and Transitions
  • Custom transition: Collection View transition when two CollectionViews are switched using navigation Controller
  • Demo provided at the beginning: iOS 7 Interactive Transition.