美文网首页iOS开发
iOS-自定义转场效果

iOS-自定义转场效果

作者: 拎着猫走的鱼 | 来源:发表于2021-03-10 10:37 被阅读0次
  • Swift5.3
  • 效果图


    效果图.gif

控制器从A——>B
在两个控制器里设置navigation的代理

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        navigationController?.delegate = self
    }

在A控制器里实现下面的方法

//MARK: Navigation Delegate
extension A控制器:UINavigationControllerDelegate,UIViewControllerAnimatedTransitioning{
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }
    
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
        return self
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        //先拿到前后两个viewcontroller 以及 实现动画的容器
        let toVC = transitionContext.viewController(forKey: .to)! as! B控制器
        let containerView = transitionContext.containerView

        //对Cell上的 imageView 截图,同时将这个 imageView 本身隐藏
        let cell = collectionView.cellForItem(at: selectIndexPath!) as! A控制器的cell
        let snapshotView = UIImageView(image: cell.imageView!.image)
        snapshotView.contentMode = .scaleAspectFit

        // 坐标转换 将cell.iconImgV的rect从其父view中转换到containerView视图中,返回在containerView视图中的rect
        snapshotView.frame = containerView.convert((cell.imageView.frame), from: cell.imageView.superview)
        cell.imageView.isHidden = true

        //设置第二个 viewController ,将它的放到过渡后的位置,但让他完全透明,我们会在过渡时给它一个淡入的效果。
        toVC.view.frame = transitionContext.finalFrame(for: toVC)
        toVC.view.alpha = 0
        toVC.imageView.isHidden = true

        //把动画前后的两个ViewController加到容器中,顺序很重要,snapShotView在上方
        containerView.addSubview(toVC.view)
        containerView.addSubview(snapshotView)

        UIView.animate(withDuration: self.transitionDuration(using: transitionContext), delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 1.0, options: .curveLinear, animations: {

            //将截图放到第二个viewController的imageView上
            snapshotView.frame = containerView.convert(toVC.imageView.frame, from: toVC.imageView.superview)
            toVC.view.alpha = 1.0

        }) { (finished) in

            snapshotView.removeFromSuperview()
            cell.imageView.isHidden = false
            toVC.imageView.isHidden = false

            //告诉系统动画结束
            transitionContext.completeTransition(true)
        }
    }

}

控制器从B——>A
在B控制器里实现下面的方法

//MARK: Navigation Delegate
extension B控制器:UINavigationControllerDelegate,UIViewControllerAnimatedTransitioning{
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.25
    }
    
    func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
        return self
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
            
            let vc = transitionContext.viewController(forKey: .to)
            //实现过渡的控制器 和 容器view
            let toVC = vc as! A控制器
            let fromVC = transitionContext.viewController(forKey: .from) as! B控制器的cell
            let containerView = transitionContext.containerView

            //前一个VC设置 截图
            let snapShotView = UIImageView(image: fromVC.imageView.image)
            snapShotView.contentMode = .scaleAspectFit
            snapShotView.frame = containerView.convert(fromVC.imageView.frame, from: fromVC.view)
            fromVC.imageView.isHidden = true
            
            //下一个VC设置
            toVC.view.frame = transitionContext.finalFrame(for: toVC)
            let cell = toVC.collectionView.cellForItem(at: selectIndexPath!) as! HomeCollectionViewCell
            cell.imageView.isHidden = true
            
            // 添加到容器
            containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
            containerView.addSubview(snapShotView)
            
            UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
                containerView.layoutIfNeeded()
                fromVC.view.alpha = 0
                snapShotView.frame = containerView.convert((cell.imageView.frame), from: cell.imageView.superview)
                
            }) { (finished) in
                
                // 告诉系统动画结束
                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
                if transitionContext.transitionWasCancelled {
                    
                    //手势取消了,原来隐藏的imageView要显示出来
                    fromVC.imageView.isHidden = false
                }else {
                    
                    //手势成功,cell的imageView也要显示出来
                    cell.imageView.isHidden = false
                }
                
                //动画交互动作完成或取消后,移除临时动画文件
                snapShotView.removeFromSuperview()
            }
        }

自定义右划返回上一页面的手势动画,在B控制器里实现下面的方法

    var transitionInteractive: HomeTransitionInteractive!

    override func viewDidLoad() {
        super.viewDidLoad()

        let interactive = HomeTransitionInteractive()
        interactive.addPanGestureForViewController(viewController: self)
        transitionInteractive = interactive
    }

    //MARK: Navigation Delegate
extension HomeCellDetailsViewController:UINavigationControllerDelegate,UIViewControllerAnimatedTransitioning{

    func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
        
        //手势开始的时候才需要传入手势过渡代理,如果直接pop或push,应该返回nil,否者无法正常完成pop/push动作
        return self.transitionInteractive.isInteractive == true ? self.transitionInteractive : nil
    }
}

自定义手势动画HomeTransitionInteractive

//
//  HomeTransitionInteractive.swift
//  PhotoCalendar
//
//  Created by Shi Jiachen on 2021/02/18.
//

import UIKit

class HomeTransitionInteractive: UIPercentDrivenInteractiveTransition {

    var viewController: UIViewController!
    var isInteractive: Bool!
    
    func addPanGestureForViewController(viewController : UIViewController) {
        
        let pan = UIPanGestureRecognizer(target: self, action: #selector(self.handleGesture(panGesture: )))
        self.viewController = viewController
        viewController.view.addGestureRecognizer(pan)
    }
    
    @objc func handleGesture(panGesture:UIPanGestureRecognizer) {
        
        let translation = panGesture.translation(in: panGesture.view)
        var percentComplete:CGFloat = 0.0
        
        //左右滑动的百分比
        percentComplete = translation.x / SCREEN_WIDTH
        percentComplete = abs(percentComplete)
//        print(percentComplete)
        
        switch panGesture.state {
        case .began:
            
            self.isInteractive = true
            self.viewController.navigationController?.popViewController(animated: true)
        
        case .changed:
            
            //手势过程中,通过updateInteractiveTransition设置转场过程动画进行的百分比,然后系统会根据百分比自动布局动画控件,不用我们控制了
            self.update(percentComplete)
            
        case .ended:
            self.isInteractive = false
            //手势完成后结束标记并且判断移动距离是否过半,过则finishInteractiveTransition完成转场操作,否者取消转场操作,转场失败
            if percentComplete > 0.35 {
                self.finish()
            }else {
                self.cancel()
            }
            
        default:
            break
        }
        
    }
}

相关文章

  • iOS-自定义转场效果

    Swift5.3 效果图效果图.gif 控制器从A——>B在两个控制器里设置navigation的代理 在A控制器...

  • 基于UIPresentationController的封装

    效果图 简单介绍 基于UIPresentationController的封装,支持多种转场效果,还可轻松自定义转场...

  • 转场动画第二弹

    iOS自定义转场详解02——实现Keynote中的神奇移动效果 关于自定义转场动画,我都告诉你。

  • iOS 自定义转场动画

    本文记录分享下自定义转场动画的实现方法,具体到动画效果:新浪微博图集浏览转场效果、手势过渡动画、网易音乐启动屏转场...

  • iOS动画(四) --自定义转场动画

    本文记录分享下自定义转场动画的实现方法,具体到动画效果:新浪微博图集浏览转场效果、手势过渡动画、网易音乐启动屏转场...

  • iOS自定义转场动画

    先看效果图: 上面就是要实现的Modal转场效果 首先,如果要自定义转场动画的话,需要设置 transitioni...

  • UITabBarController切换谈入谈出效果

    iOS7之后通过自定义转场我们可以对切换动画效果进行定制,下面介绍一种不进行自定义转场地淡入淡出效果实现tabBa...

  • iOS-OC-可交互自定义转场动画,带你填坑

    上一章写了不可交互的自定义转场动画,这一章写写可交互的自定义转场动画,先来效果图。 进入正题 可交互转场主要依赖于...

  • swift自定义简单的转场动画

    效果图: 主要思路:遵循两个代理:转场代理和转场动画代理 在转场代理中自定义转场类:在里面实现对添加的view的f...

  • iOS自定义转场动画

    更新,更简单的自定义转场集成! 几句代码快速集成自定义转场效果+ 全手势驱动 写在前面 这两天闲下来好好的研究了一...

网友评论

    本文标题:iOS-自定义转场效果

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