MyViewController *myVC = [[MyViewController alloc]init]; [CATransition animation]; / / set the speed of motion animation timingFunction = UIViewAnimationCurveEaseInOut; // Set the animation type to cube animation.type = @"cube"; Animation. duration =0.5f; Animation. subtype =kCATransitionFromRight; // Controller jump animation [[UIApplication sharedApplication].keywindow. layer addAnimation:animationforKey:nil];
[self presentViewController:myVC animated:NO completion:nil];
Copy the code
Here are some commonly used animation types:     Fade = 1, // Fade in and Fade out Push, // Push Reveal, // uncover MoveIn, // overlay Cube, // Suck OglFlip, // flip RippleEffect, CameraIrisHollowClose, CameraIrisHollowClose, camerairishollowDown, camerairIshollowDown, camerairIshollowUp, Flip FlipFromLeft / /, / / left turn Attach Jane book the great spirit of the article: http://www.jianshu.com/p/09b7e5ff371c FlipFromRight, / / right turnCopy the code

Simple custom ViewController jump animation

When I learned iOS animation, I was always motivated by other people’s cool animation effects. After learning how to customize, I found that it was not that difficult. Some animations that can be realized in UIView, such as gradient, flip and translation, can be put into jump animation.

The principle of

When we switch views, whether it’s push, pop or through PresentModal and dismiss, we can split the jump animation into three parts,

1: First view controller is displayed.

2: Temporary view controller displays animations (there’s not really a controller, there’s only one containerView)

3: Displays the second view controller. To put it more visually, we can also view the second part as a temporary view controller, and it’s doing an animation of UIView, and we just have the animation start like controller 1 and end like view Controller 2. When the animation ends and the third step is performed, release the temporary view controller. So with a little bit of UIView, CALayer animation,

Specific implementation method: The effect of the following figure is an example:

Protocols and methods used

@protocol UIViewControllerAnimatedTransitioning
Copy the code

The objects that implement this protocol act as temporary view controllers, and the two main methods used in this protocol are:

/ / this method we just return the execution time of page jump animation - (NSTimeInterval) transitionDuration: (id < UIViewControllerContextTransitioning >)transitionContext; / / in this method to achieve specific animation - (void) animateTransition: (id < UIViewControllerContextTransitioning >) transitionContext;Copy the code

The second method jumps to the animation core, where the transitionContext parameter is the context of the current temporary controller interface. So by context, we’re going to get the background view of the temporary view controller containerView, which already has a child view, fromViewController.view. So what we’re going to do is, we’re going to get the toViewController

UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
Copy the code

Then add the current view to the content view

[[transitionContext containerView] addSubview:toVC.view];
Copy the code

The rest can play to our system’s core animation learning level, such as modifying the frame of tovc. view, rotating and popping from below, etc. To do what we saw in the Demo, we need a CAShapeLayer to mask the toView, and then change the shapelayer. path property from a small circle to a large circle that covers the full screen. Small circles and large circles we draw through UIBezierPath, Students who are not familiar with ShapeLayer and UIBezierPath can go to the tutorial first, the specific use here is not complicated, you can also directly look at the following code to learn.

// The screen height of the application#define kWindowH [UIScreen mainScreen].bounds.size.height// The screen width of the application#define kWindowW [UIScreen mainScreen].bounds.size.width_circleCenterRect = CGRectMake(120, 320, 50, 50); / / circle 1 - small round UIBezierPath * smallCircleBP = [UIBezierPath bezierPathWithOvalInRect: _circleCenterRect]; / / 2 - circle circle / / CGFloat centered on the center of the _circleCenterRect centerX = _circleCenterRect. Origin. X + _circleCenterRect. Size. The width / 2; CGFloat centerY = _circleCenterRect.origin.y+_circleCenterRect.size.height/2; CGFloat R1 = (kwindoww-centerx)>centerX? (kWindowW-centerX):centerX; CGFloat r2 = (kWindowW-centerY)>centerY? (kWindowW-centerY):centerY; CGFloat radius = sqrt((r1 * r1) + (r2 * r2)); UIBezierPath *bigCircleBP = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(_circleCenterRect, -radius, -radius)]; // Set maskLayer CAShapeLayer *maskLayer = [CAShapeLayer layer]; // Specify its path as the final path to avoid bouncing back after animation tovc.view.layer. mask = maskLayer; maskLayer.path = bigCircleBP.CGPath; CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
maskLayerAnimation.fromValue = (__bridge id)(smallCircleBP.CGPath);
maskLayerAnimation.toValue = (__bridge id)((bigCircleBP.CGPath));
maskLayerAnimation.duration = [self transitionDuration:transitionContext];
maskLayerAnimation.delegate = self;
[maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
Copy the code

The animation effect when returning is basically the same as the code above. We only need to switch the order of the large circle and the small circle to complete the core part of the jump animation, which is how to use the object. Whether navigation or modal jump, the system provides us callback methods, we just need to implement methods. And then we can just return the animation object that we wrote earlier. Since shapelayer is added to the view, it can be implemented in the proxy method of CABasicAnimation.

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{// tell the system that the transition is completed [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]]; // Clear fromVC mask [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil; [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil; }Copy the code
@protocol UINavigationControllerDelegate
Copy the code

This is the protocol that needs to be implemented to modify the Navigation jump animation. When we jump through pop or push, the following method will be called (other methods of the protocol will not be described because they are not needed for the time being). We can see that the return value is ID, which is the animation object we wrote earlier.

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                               animationControllerForOperation:(UINavigationControllerOperation)operation
                                            fromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC;
Copy the code

Method of operation parameter is an enumeration type, we can judge it is the value of the UINavigationControllerOperationPush or

UINavigationControllerOperationPop to distinguish the current way of jump.

@protocol UIViewControllerTransitioningDelegate
Copy the code

This is the protocol we need to implement to modify the modal jump animation. When we make a jump PresentModal and dismiss, we call two methods:

//PresentModal jump callback method - (Nullable ID <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presentingsourceController:(UIViewController *)source; // Dismiss jump callback method - (nullable ID <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;Copy the code

These two methods of return values and top navigation callback method return values, we only need to initialize our implementation UIViewControllerTransitioningDelegate animation object of the agreement. See the Demo attached at the end of this article for details of the implementation and effects.

Where navigation jumps need attention

When using Navigation jump, we want view 1 to jump to View 2 and view 2 to return to view 1 with custom animation, we only set delagate of view 1’s Navigation in view 1. Second, the delegate Settings are best placed in viewWillAppear.

The end result of the demo is only a jump animation when the button is clicked, not a gesture animation like a navigation slide back. To prevent the sideslip effect from being inconsistent, we can first turn off the sideslip effect:

self.navigationController.interactivePopGestureRecognizer.enabled = NO; // TODO: gesture jump animation implementation method (pit to be filled)Copy the code