IOS custom transfer animation (lower)

Source: Internet
Author: User

IOS custom transfer animation (lower)

Add UIViewControllerAnimatedTransitioning

Add a Cocoa Touch Class, inherit from NSObject, and name it BWFlipTransionPush (the name is nice .), Comply with the UIViewControllerAnimatedTransitioning protocol.

Two methods for implementing the Protocol, and write the Push animation in it. The specific animation implementation process is included in the code comment:

Func animateTransition (transitionContext: UIViewControllerContextTransitioning ){

LetfromVC = transitionContext. viewControllerForKey (UITransitionContextFromViewControllerKey)! FirstViewController

LettoVC = transitionContext. viewControllerForKey (UITransitionContextToViewControllerKey)! SecondViewController

Letcontainer = transitionContext. containerView ()

Container. addSubview (toVC. view)

Container. bringSubviewToFront (fromVC. view)

 

// Change m34

Vartransfrom = CATransform3DIdentity

Transfrom. m34 =-0.002

Container. layer. sublayerTransform = transfrom

 

// Set anrchPoint and position

LetinitalFrame = transitionContext. initialFrameForViewController (fromVC)

ToVC. view. frame = initalFrame

FromVC. view. frame = initalFrame

FromVC. view. layer. anchorPoint = CGPointMake (0, 0.5)

FromVC. view. layer. position = CGPointMake (0, initalFrame. height/2.0)

 

// Add a shadow effect

LetshadowLayer = CAGradientLayer ()

ShadowLayer. colors = [UIColor (white: 0, alpha: 1 ). CGColor, UIColor (white: 0, alpha: 0.5 ). CGColor, UIColor (white: 1, alpha: 0.5)]

ShadowLayer. startPoint = CGPointMake (0, 0.5)

ShadowLayer. endPoint = CGPointMake (1, 0.5)

ShadowLayer. frame = initalFrame

Letshadow = UIView (frame: initalFrame)

Shadow. backgroundColor = UIColor. clearColor ()

Shadow. layer. addSublayer (shadowLayer)

FromVC. view. addSubview (shadow)

Shadow. alpha = 0

 

// Animation

UIView. animateWithDuration (transitionDuration (transitionContext), delay: 0, options: UIViewAnimationOptions. CurveEaseOut, animations: {()-> Voidin

FromVC. view. layer. transform = CATransform3DMakeRotation (CGFloat (-M_PI_2), 0, 1, 0)

Shadow. amp; alpha = 1.0

}) {(Finished: Bool)-> Voidin

FromVC. view. layer. anchorPoint = CGPointMake (0.5, 0.5)

FromVC. view. layer. position = CGPointMake (CGRectGetMidX (initalFrame), CGRectGetMidY (initalFrame ))

FromVC. view. layer. transform = CATransform3DIdentity

Shadow. removeFromSuperview ()

 

TransitionContext. completeTransition (! TransitionContext. transitionWasCancelled ())

}

}

I will not talk much about the animation process. I will understand it after careful reading.

Use Animation

Make FirstViewController comply with the UIViewControllerTransitioningDelegate protocol, and set self. transitioningDelegate to self.

Two methods for implementing the UIViewControllerTransitioningDelegate protocol are used to specify the animation class.

// Animation Push

Func animationControllerForPresentedController (presented: UIViewController, presentingControllerpresenting: UIViewController, sourceControllersource: UIViewController)-> UIViewControllerAnimatedTransitioning? {

ReturnBWFlipTransionPush ()

}

// Animated Pop

Func animationControllerForDismissedController (dismissed: UIViewController)-> UIViewControllerAnimatedTransitioning? {

ReturnBWFlipTransionPop ()

}

OK. If you have completed the Pop animation, you can now customize Modal transfer. Now it's just a gesture drive.

Gesture-driven

To implement Push and Pop gestures at the same time, you need to add gestures to two viewController. Views. First, add a gesture to the right of the screen to the FirstViewController, and add a gesture to the left of the screen to SecondViewController. view in the prepareForSegue () method so that they can use the same gesture listening method.

The method for implementing the listener is the same as before, but you should take a closer look, because the transfer field animation in this example is special and there are two gestures, so the percentage calculation here uses KeyWindow. Do not forget the UIPercentDrivenInteractiveTransition attribute.

Func edgePanGesture (edgePan: UIScreenEdgePanGestureRecognizer ){

Letprogress = abs (edgePan. translationInView (UIApplication. sharedApplication (). keyWindow !). X)/UIApplication. sharedApplication (). keyWindow !. Bounds. width

 

IfedgePan. state = UIGestureRecognizerState. Began {

Self. percentDrivenTransition = UIPercentDrivenInteractiveTransition ()

IfedgePan. edges = UIRectEdge. Right {

Self. inclumseguewithidentifier ("present", sender: nil)

} ElseifedgePan. edges = UIRectEdge. Left {

Self. dismissViewControllerAnimated (true, completion: nil)

}

} ElseifedgePan. state = UIGestureRecognizerState. Changed {

Self. percentDrivenTransition ?. UpdateInteractiveTransition (progress)

} ElseifedgePan. state = UIGestureRecognizerState. Cancelled | edgePan. state = UIGestureRecognizerState. Ended {

Ifprogress & gt; 0.5 {

Self. percentDrivenTransition ?. FinishInteractiveTransition ()

} Else {

Self. percentDrivenTransition ?. CancelInteractiveTransition ()

}

Self. percentDrivenTransition = nil

}

}

The other two methods that implement the UIViewControllerTransitioningDelegate protocol return the percentages of the Present and Dismiss animations respectively.

// Percentage Push

Func interactionControllerForPresentation (animator: UIViewControllerAnimatedTransitioning)-> UIViewControllerInteractiveTransitioning? {

Returnself. percentDrivenTransition

}

// Percentage Pop

Func interactionControllerForDismissal (animator: UIViewControllerAnimatedTransitioning)-> UIViewControllerInteractiveTransitioning? {

Returnself. percentDrivenTransition

}

Now, the Modal-based custom transition animation example is complete. Obtain the complete source code: FlipTransion

Segue

This method is special. It is used to bind the drag and drop lines in the Stroyboard with the custom UIStoryboardSegue class to customize the transition process animation.

First, let's take a look at what UIStoryboardSegue looks like.

@ Availability (iOS, introduced = 5.0)

ClassUIStoryboardSegue: NSObject {

 

// Convenience constructor for returning a segue that performs a handler block in its-perform method.

@ Availability (iOS, introduced = 6.0)

Convenience init (identifier: String ?, Source: UIViewController, destination: UIViewController, javasmhandler :()-> Void)

 

Init! (Identifier: String ?, Source: UIViewController, destination: UIViewController) // Designated initializer

 

Varidentifier: String? {Get}

VarsourceViewController: AnyObject {get}

VardestinationViewController: AnyObject {get}

 

Func perform ()

}

The above is the definition of UIStoryboardSegue class. We can see that there is only one method, perform (), so it is obvious that this method is rewritten to customize the transition animation.

Pay attention to its other attributes: sourceViewController and destinationViewController. With these two attributes, we can access the two protagonists in a transition animation, so that we can customize the animation as we like.

Note only one point: when dragging a line, select custom in the pop-up options. Then you can bind it to the custom UIStoryboardSegue.

So the question is, here only the perform is available. What should we do with the animation returned? Please refer to the following link:

Dismiss

Since the perfrom method is called: segue, the previous controller returned to the transfer is called: unwind segue.

The unwind track usually appears together with the normal custom track.

To cancel the transition, we must override the perform method and apply the Custom Animation. In addition, the transition effect of the navigation back source View Controller does not need to be the same as that of the corresponding normal transition.

The implementation steps are as follows:

Create an IBAction method that selectively executes some code when the transfer is canceled. This method can have any name you want and does not include anything else. It needs to be defined, but can be left blank. This method is required to remove the definition of transfer.
 

Release the transfer creation and configuration. This is not the same as the previous transfer creation. Let's wait and see how this is implemented.
 

You can override the perform () method in the UIStoryboardSegue subclass to implement Custom Animation.
 

The UIViewController class provides the definition of a specific method, so the system knows that the transfer is about to be executed.

Of course, there are some things that are hard to understand and do not know what it means. Next, let's take a further look at it through an example.

Example

This example is written by myself. The Source Code address is SegueTransion.

Create two uiviewcontrollers named FirstViewController and SecondViewController respectively. Add two uiviewcontrollers to the Storyboard and bind them.

Add a background image to the two controllers or use a different background color for distinguishing. Add a trigger button in FirstViewController, drag the button to SecondViewController, and select custion in the pop-up options.

 

Add a Cocoa Touch Class that inherits from UIStoryboardSegue and is named FirstSegue ). And bind it to the segue dragged in the previous step.

Override the perform () method in FirstSegue and write the animation logic in it.

 

Override func perform (){

VarfirstVCView = self. sourceViewController. viewasUIView!

VarsecondVCView = self. destinationViewController. viewasUIView!

 

LetscreenWidth = UIScreen. mainScreen (). bounds. size. width

LetscreenHeight = UIScreen. mainScreen (). bounds. size. height

 

SecondVCView. frame = CGRectMake (0.0, screenHeight, screenWidth, screenHeight)

Letwindow = UIApplication. sharedApplication (). keyWindow

Window ?. InsertSubview (secondVCView, aboveSubview: firstVCView)

 

UIView. animateWithDuration (0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: UIViewAnimationOptions. CurveLinear, animations: {()-> Voidin

SecondVCView. frame = CGRectOffset (secondVCView. frame, 0.0,-screenHeight)

}) {(Finished: Bool)-> Voidin

Self. sourceViewController. presentViewController (self. destinationViewControlleras! UIViewController,

Animated: false,

Completion: nil)

}

}

 

The animation process is quite simple.

 

Present gesture

 

Note that a custom transition animation cannot be dynamically driven by a gesture, that is, it cannot dynamically change the animation completion degree based on the gesture percentage.

Therefore, we simply add a slide gesture (swip ).

 

Add a gesture to FisrtViewController:

 

VarswipeGestureRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer (target: self, action: "showSecondViewController ")

SwipeGestureRecognizer. direction = UISwipeGestureRecognizerDirection. Up

Self. view. addGestureRecognizer (swipeGestureRecognizer)

 

How to Implement gesture listening:
 

Func showSecondViewController (){

Self. inclumseguewithidentifier ("idFirstSegue", sender: self)

}

 

Now the present is ready, and dismiss is implemented.

 

Dismiss

 

Add an IBAction method to FirstViewController. The method name can be used as needed.

On the Storyboard, select SecondViewController and press and hold the control key to drag the line to the Exit icon of SecondViewController. In the pop-up options, select the method for adding IBAction in the previous step.

In the document view on the left side of the Storyboard, find the last drag seue and Set identifier

Add a Cocoa Touch Class that inherits from UIStoryboardSegue and is named FirstSegueUnWind ). And rewrite its perform () method to implement the dismiss animation.

In FirstViewController, rewrite the following method. Determine whether or not dismiss is required based on the identifier. If yes, the created FirstUnWindSegue is returned.

Override func segueForUnwindingToViewController (toViewController: UIViewController, fromViewController: UIViewController, identifier: String ?) -> UIStoryboardSegue {

 

Ifidentifier = "firstSegueUnwind "{

ReturnFirstUnwindSegue (identifier: identifier, source: fromViewController, destination: toViewController, receivmhandler: {()-> Voidin

})

}

 

Returnsuper. segueForUnwindingToViewController (toViewController, fromViewController: fromViewController, identifier: identifier)

}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.