自定义presentViewController的转场动画(Swift)

自定义presentViewController的转场动画(Swift),第1张

概述原创Blog,转载请注明出处 我的StackFlow 前言: iOS默认的presentViewController的切换动画是从底部推入,消失是从顶部推出。但是,因为iOS系统默认的是适配所有转场上下文的。而针对特定的转场上下文,我们能做出更好的效果。 Tips:所谓的转场上下文,就是转场的开始View和结束View,以及对应的ViewController 目标效果 最终的效果 准备工作 首先写

原创Blog,转载请注明出处

我的StackFlow

前言:

iOS默认的presentVIEwController的切换动画是从底部推入,消失是从顶部推出。但是,因为iOS系统默认的是适配所有转场上下文的。而针对特定的转场上下文,我们能做出更好的效果。

Tips:所谓的转场上下文,就是转场的开始VIEw和结束VIEw,以及对应的VIEwController

目标效果

最终的效果

准备工作

首先写出一个CollectionVIEw,每个Cell是一个图片,由于本文的核心是如何转场,所以CollectionVIEw的部分略过。写完了之后,是这样的效果

点击某一个CollectionVIEw Cell查看大图,再点击大图图片消失

这个最初的项目,可以在这里下载

CSDN下载

如何实现自定义转场动画

iOS 8之后,我们可以通过设置VIEwControllerTransitioningDelegate来设置代理来处理转场动画。

通过文档,可以看到TransitioningDelegate是一个实现UIVIEwControllerTransitioningDelegate协议的对象,先看看这个协议,本文主要利用以下两个方法

animationControllerFordismissedController animationControllerForPresentedController

着两个方法的目的是,提供一个遵循UIVIEwControllerAnimatedTransitioning协议的对象,然后又这个对象来实际处理专场。通过名字就可以看出来,一个是处理present一个是处理dismiss。

本文的设计是让VIEwController来处理转场,在dIDSelectItemAtIndexPath中,设置pvc的转场代理

dvc.TransitioningDelegate = self

然后,写一个extension来实现协议

extension VIEwController:UIVIEwControllerTransitioningDelegate{    func animationControllerFordismissedController(dismissed: UIVIEwController) -> UIVIEwControllerAnimatedTransitioning? {        return nil    }    func animationControllerForPresentedController(presented: UIVIEwController,presentingController presenting: UIVIEwController,sourceController source: UIVIEwController) -> UIVIEwControllerAnimatedTransitioning? {        return nil    }}

这时候,再运行项目,会发现没有任何变化,还是默认的转场方式。因为我们还没有提供实际的动画 。当上述两个代理方法返回nil的时候,系统会使用默认的方式

实现UIVIEwControllerAnimatedTransitioning

新建一个文件,命名为Animator.swift,然后新建一个类,处理Present的转场(dismiss类似),实现UIVIEwControllerAnimatedTransitioning协议

class PresentAnimator: NSObject,UIVIEwControllerAnimatedTransitioning{

这时候,会报错没有实现协议,然后,我们添加协议方法,这时候的Animator.swift如下

import Foundationimport UIKitclass PresentAnimator: NSObject,UIVIEwControllerAnimatedTransitioning{    let duration = 0.5 //动画的时间    var originFrame = CGRectZero //点击Cell的frame    func TransitionDuration(TransitionContext: UIVIEwControllerContextTransitioning?) -> NSTimeInterval {        return duration    }    func animateTransition(TransitionContext: UIVIEwControllerContextTransitioning) {    }}

简单介绍下这里的协议方法

TransitionDuration,返回转场动画的时间 animateTransition,进行实际的转场动画,通过参数TransitionContext(转场上下文)来获取转场的fromVIEw,toVIEw,fromVIEwController,toVIEwController。 转场的原理 转场开始的时候,自动把FromVIEw添加到转场ContainVIEw 转场结束的时候,自动把FromVIEw移除ContainVIEw

所以,开发者要做的就是

把toVIEw添加到转场ContainVIEw中,并且定义好toVIEw的初始位置和状态 定义好FromVIEw和ToVIEw的转场结束时候的状态 创建动画 实现实际的转场动画

基于上述的原理,我们修改实际的动画

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)        }    }

然后,在VIEwController.swfit中,添加一属性

let presentAnimator = PresentAnimator()

修改dIDSelectItemAtIndexPath

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)    }

修改代理方法

func animationControllerForPresentedController(presented: UIVIEwController,sourceController source: UIVIEwController) -> UIVIEwControllerAnimatedTransitioning? {        return presentAnimator    }

这时候的动画效果如Gif

同理,为dismiss添加转场动画

在Animator.swift中添加一个新的类

class dismisssAnimator:NSObject,UIVIEwControllerAnimatedTransitioning{    let duration = 0.6    var originFrame = CGRectZero    func TransitionDuration(TransitionContext: UIVIEwControllerContextTransitioning?) -> NSTimeInterval {        return duration    }    func animateTransition(TransitionContext: UIVIEwControllerContextTransitioning) {        let containVIEw = TransitionContext.containerVIEw()        let toVIEw = TransitionContext.vIEwForKey(UITransitionContextToVIEwKey)! //Collection VIEw        let fromVIEw = TransitionContext.vIEwForKey(UITransitionContextFromVIEwKey)! //全屏的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)        }    }}

然后,在VIEwController.swift中dIDSelectItemAtIndexPath设置presentAnimator.frame下一行添加

dismissAnimator.originFrame = cell.convertRect(cell.imagevIEw.frame,toVIEw: nil)

其中,dismissAnimator是VIEwController的一个属性

let dismissAnimator = dismisssAnimator()

然后,在代理方法中,返回

func animationControllerFordismissedController(dismissed: UIVIEwController) -> UIVIEwControllerAnimatedTransitioning? {        return dismissAnimator;    }

最终的效果

完整工程的下载

CSDN下载

总结

以上是内存溢出为你收集整理的自定义presentViewController的转场动画(Swift)全部内容,希望文章能够帮你解决自定义presentViewController的转场动画(Swift)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1077322.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存