Custom transition animation of presentViewController (Swift)

Source: Internet
Author: User

Custom transition animation of presentViewController (Swift)
Preface:

IOS defaultpresentViewControllerThe switching animation is pushed from the bottom, and disappears from the top. However, by default, the iOS system is applicable to all transfer contexts. For specific transfer context, we can make better results.

Tips: the so-called transfer context is the start View and end View of the transfer, and the corresponding ViewController

Target Effect

Final Effect

Preparations

First, writeCollectionViewEach Cell is an image. Because the core of this article is how to transferCollectionView. This is the result after writing.

Click a CollectionView Cell to view the larger image, and then click the larger image to disappear.

 

How to Implement custom transfer Animation

After iOS 8, we can setViewControllerOftransitioningDelegateTo set a proxy to process the transition animation.

You can see through the documenttransitioningDelegateIs an implementationUIViewControllerTransitioningDelegateThe object of the Protocol. This article mainly uses the following two methods:

AnimationControllerForDismissedController animationControllerForPresentedController

The purpose of the two methods is to provideUIViewControllerAnimatedTransitioningThe object of the protocol, and then the object is used to actually process the session. We can see from the name that one is processing the present and the other is processing the dismiss.

The design in this article isViewControllerIndidSelectItemAtIndexPath, Set pvc transfer proxy

dvc.transitioningDelegate = self

Then, write an extension to implement the Protocol.

extension ViewController:UIViewControllerTransitioningDelegate{    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return nil    }    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return nil    }}

When you run the project again, you will find that there is no change, or the default transfer mode. Because we have not provided the actual animation. When the above two proxy Methods return nil, the system will use the default method

Implement UIViewControllerAnimatedTransitioning

Create a new file named Animator. swift, and create a new class to process the transferred field of the Present (similar to Dismiss), and implement the UIViewControllerAnimatedTransitioning protocol.

class PresentAnimator: NSObject,UIViewControllerAnimatedTransitioning{}

At this time, an error will be reported that the Protocol is not implemented. Then, we add the Protocol method. At this time, the Animator. swift is as follows:

Import Foundationimport UIKitclass PresentAnimator: NSObject, duration {let duration = 0.5 // animation time var originFrame = CGRectZero // click the frame func transitionDuration (transitionContext: duration?) of the Cell ?) -> NSTimeInterval {return duration} func animateTransition (transitionContext: UIViewControllerContextTransitioning ){}}

Briefly introduce the Protocol method here

TransitionDuration: returns the animation time animateTransition. The actual animation is used to obtain the fromView, toView, fromViewController, and toViewController of the transition through the transitionContext parameter. Transfer Principle

When the transfer starts, the FromView is automatically added to the inview when the transfer ends, and the FromView is automatically removed from the ContainView

So what developers need to do is

Add toView to inview, and define the initial position and status of toView. Define the State creation animation at the end of FromView and ToView. Real transfer Animation

Based on the above principle, we modify the actual Animation

     func animateTransition(transitionContext: UIViewControllerContextTransitioning) {        let containView = transitionContext.containerView()        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!        let finalFrame = toView.frame        let xScale = originFrame.size.width/toView.frame.size.width        let yScale = originFrame.size.height/toView.frame.size.height        toView.transform = CGAffineTransformMakeScale(xScale, yScale)        toView.center = CGPointMake(CGRectGetMidX(originFrame), CGRectGetMidY(originFrame))        containView?.addSubview(toView)        UIView.animateWithDuration(duration, animations: { () -> Void in            toView.center = CGPointMake(CGRectGetMidX(finalFrame), CGRectGetMidY(finalFrame))            toView.transform = CGAffineTransformIdentity            }) { (finished) -> Void in                transitionContext.completeTransition(true)        }    }

Then, add an attribute in viewcontroller.swf it.

    let presentAnimator = PresentAnimator()

ModifydidSelectItemAtIndexPath

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {        let dvc = DetailViewController()        dvc.image = UIImage(named: "image.jpg")        dvc.transitioningDelegate = self        let cell =  collectionView.cellForItemAtIndexPath(indexPath) as! FullImageCell        presentAnimator.originFrame = cell.convertRect(cell.imageview.frame, toView: nil)        self.presentViewController(dvc, animated: true, completion: nil)    }

Modify proxy method

    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return presentAnimator    }

At this time, the animation effect is like Gif.

Similarly, add a transfer animation for dismiss.

Add a new class to Animator. swift.

Class DismisssAnimator: NSObject, UIViewControllerAnimatedTransitioning {let duration = 0.6 var originFrame = CGRectZero func transitionDuration (transitionContext: UIViewControllerContextTransitioning ?) -> NSTimeInterval {return duration} func animateTransition (transitionContext: interval) {let containView = transitionContext. containerView () let toView = transitionContext. viewForKey (UITransitionContextToViewKey )! // Collection View let fromView = transitionContext. viewForKey (UITransitionContextFromViewKey )! // Full screen imageview let xScale = originFrame. size. width/toView. frame. size. width let yScale = originFrame. size. height/toView. frame. size. height containView ?. AddSubview (toView) containView ?. BringSubviewToFront (fromView) UIView. animateWithDuration (duration, animations: {()-> Void in fromView. center = CGPointMake (CGRectGetMidX (self. originFrame), CGRectGetMidY (self. originFrame) fromView. transform = CGAffineTransformMakeScale (xScale, yScale)}) {(finished)-> Void in transitionContext. completeTransition (true )}}}

Then, in ViewController. swiftdidSelectItemAtIndexPathSet presentAnimator. frame to add

 dismissAnimator.originFrame = cell.convertRect(cell.imageview.frame, toView: nil)

DismissAnimator is an attribute of ViewController.

    let dismissAnimator = DismisssAnimator()

Then, in the proxy method, return

 func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return dismissAnimator;    }

Final Effect

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.