美文网首页
swift自定义转场动画

swift自定义转场动画

作者: U小姐咯 | 来源:发表于2016-08-15 18:45 被阅读141次

    在新浪微博的首页部分,点击用户名会向下弹出一个表格,如下图:

    下拉视图.png
    我用模态弹出视图,但是系统的效果是从下往上弹出的,所以我们需要通过自定义转场动画,来达到我们想要的效果.详细效果大家可以打开新浪微博试试哦(ps:我的新浪微博ID是:U小姐咯.四个字哦,如图所示,欢迎关注😄).
    1⃣️.为了简洁代码,我们用xib搭配,首先创建一个PopViewController并在xib拖入黑色带箭头的图片,并放上表格,进行一下适配.
    2⃣️.接下来自定义一个DMPresentationController继承于UIPresentationController,代码如下
    class DMPresentationController: UIPresentationController {
    
        //如果不自定义转场,modal出来的控制器会移除原有的控制器,自定义的则不会
        //自定义可以改变控制器的尺寸和屏幕不一样
        var presentFrame = CGRectZero
        override init(presentedViewController : UIViewController,presentingViewController : UIViewController) {
            super.init(presentedViewController: presentedViewController, presentingViewController: presentingViewController)
        }
        //用于布局转场动画弹出的控件
        override func containerViewWillLayoutSubviews() {
            //这个属性是容器,所有弹出的的视图都是放在这里面的
           //  containerView
           // presentedView()  通过方法拿到弹出视图
            presentedView()?.frame = presentFrame
            
            //添加蒙版,点击btn让图层收起来
           // containerView?.addSubview(coverBtn)
            //0代表最底层
            containerView?.insertSubview(coverBtn, atIndex: 0)
            coverBtn.addTarget(self, action: #selector(DMPresentationController.touch), forControlEvents: UIControlEvents.TouchUpInside)
        }
        
        func touch(){
    presentedViewController.dismissViewControllerAnimated(true, completion: nil)
        }
        //MARK:懒加载
        private var coverBtn : UIButton = {
            let btn = UIButton.init(type: UIButtonType.Custom)
            btn.frame = UIScreen.mainScreen().bounds
            return btn
        }()
    }
    

    3⃣️.我们自定义了转场动画,还需要一个负责转场动画的对象,创建DMPresentationManager继承NSObject,管理我们需要的效果.代码如下:

    class DMPresentationManager: NSObject,UIViewControllerTransitioningDelegate,UIViewControllerAnimatedTransitioning {
        var managerFrame = CGRectZero
        private var isPresent = false
        //该方法返回一个负责转场动画的对象
        //可以在该对象中控制弹出视图的尺寸
        func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController? {
            let presentVc = DMPresentationController.init(presentedViewController: presented, presentingViewController: presenting)
            presentVc.presentFrame = managerFrame
            return presentVc
        }
        //该方法用于返回一个负责转场如何出现的对象
        func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?{
            //遵守协议,消失就会调用
            isPresent = !isPresent
            //发送通知,通知状态发生改变
    NSNotificationCenter.defaultCenter().postNotificationName(DMPresentationManagerPresented, object: self)
            return self
        }
        //用于返回一个负责转场如何消失的对象
        func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{
            isPresent = !isPresent
            NSNotificationCenter.defaultCenter().postNotificationName(DMPresentationManagerDismissed, object: self)
            return self
        }
        //MARK:UIViewControllerAnimatedTransitioning
        //告诉系统展现和小时的动画时长
        func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval{
            //这个方法设置执行动画的时间
            return 0.3
        }
        //用于管理modal如何展现和消失,都会调用这个方法
        //只要实现了这个代理方法,系统就不会添加默认的动画,所有动画操作需要自己实现,包括需要展现的视图也需要自己添加到容器视图上(containerView)
        //transitionContext,所有动画都保存在上下文中,就是可以通过transitionContext获取我们想要的东西
        func animateTransition(transitionContext: UIViewControllerContextTransitioning){
            //展现或者消失都会调用这个方法
            
            if isPresent {
                //获取需要弹出视图
                //UITransitionContextFromViewKey, and UITransitionContextToViewKey
                presentAnimation(transitionContext)
            }else{
                
                dismissedAnimation(transitionContext)
            }
        }
        private func presentAnimation(transitionContext: UIViewControllerContextTransitioning){
            guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else{
                return
            }
            //将需要弹出视图添加到containerView上
            transitionContext.containerView()?.addSubview(toView)
            //执行动画
            toView.transform = CGAffineTransformMakeScale(1.0, 0.0)
            //设置锚点
            toView.layer.anchorPoint = CGPoint(x: 0.5,y: 0)
            UIView.animateWithDuration(0.3, animations: { () ->Void in
                toView.transform = CGAffineTransformIdentity
            }) { (_)-> Void in  //下划线代表忽略这个值
                //自定义转场动画,执行完之后一定要告诉系统动画执行完毕了
                transitionContext.completeTransition(true)
            }
        }
        private func dismissedAnimation(transitionContext: UIViewControllerContextTransitioning){
            guard let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else{
                return
            }
            UIView.animateWithDuration(1, animations: { () ->Void in
                fromView.transform = CGAffineTransformMakeScale(1.0, 0.000000)
            }) { (_)-> Void in  //下划线代表忽略这个值
                //自定义转场动画,执行完之后一定要告诉系统动画执行完毕了
                transitionContext.completeTransition(true)
            }
        }
    }
    

    4⃣️.接下来我们实现点击按钮可以弹出我们自定义的视图

    let popVc = PopViewController()
            //自定义转场动画
            //设置代理
            popVc.transitioningDelegate = animationManager
            //设置样式
            popVc.modalPresentationStyle = UIModalPresentationStyle.Custom
            presentViewController(popVc, animated: true, completion: nil)
    
     //MARK:懒加载
        lazy var animationManager :DMPresentationManager = {
            let manager = DMPresentationManager()
     //这里我们对需要弹出视图的frame进行相应的设置
            manager.managerFrame = CGRectMake(100, 60, 200, 320)
            return manager
        }()
    

    以上😄

    相关文章

      网友评论

          本文标题:swift自定义转场动画

          本文链接:https://www.haomeiwen.com/subject/jlwusttx.html