Swift:Lottie实现tabBar切换动画

主要是利用lottie实现tabbar切换时的动画效果,如下图所示
lottie 实现tabbar切换动画.gif

  • 1、首先需要创建 继承自UITabBarController 的视图控制器 HomeTabBarController
  • 2、pod lottie框架
  • 3、添加 HomeTabBarController的子控制器视图
extension HomeTabBarController{
    fileprivate func setupChildVC(){
        
        let first = UIViewController()
        first.view.backgroundColor = UIColor.yellow
        
        let second = UIViewController()
        second.view.backgroundColor = UIColor.green
        
        let third = UIViewController()
        third.view.backgroundColor = UIColor.purple
        
        let fourth = UIViewController()
        fourth.view.backgroundColor = UIColor.white
        
        setTabbarChild(first, title: "首页", img: "tabBar_home_normal", selectImg: "tabBar_home_selected")
        setTabbarChild(second, title: "通话", img: "tabBar_call_normal", selectImg: "tabBar_call_selected")
        setTabbarChild(third, title: "联系人", img: "tabBar_link_normal", selectImg: "tabBar_link_selected")
        setTabbarChild(fourth, title: "消息", img: "tabBar_message_normal", selectImg: "tabBar_message_selected")
    }
    
    private func setTabbarChild(_ vc: UIViewController,title: String, img: String, selectImg: String){
        let vc = vc
//        vc.view.backgroundColor = UIColor.white
        let nvc = UINavigationController(rootViewController: vc)
        nvc.tabBarItem.title = title
        
        var image = UIImage(named: img)
        image = image?.withRenderingMode(.alwaysOriginal)
        nvc.tabBarItem.image = image
        
        var selectImage = UIImage(named: img)
        selectImage = selectImage?.withRenderingMode(.automatic)
        nvc.tabBarItem.selectedImage = selectImage
        
        nvc.tabBarItem.imageInsets = UIEdgeInsets(top: -1.5, left: 0, bottom: 1.5, right: 0)
        self.addChild(nvc)
    }
  • 4、通过重写UITabBarControllerDelegate中的tabBarController:didSelect:代码方法实现 tabbar切换时的动画效果
extension HomeTabBarController: UITabBarControllerDelegate{
    
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        setupAnimation(tabBarController, viewController)
    }
    
    private func getAnimationViewAtTabBarIndex(_ index: Int, _ frame: CGRect)-> AnimationView{
            
        // tabbar1 。。。 tabbar3
        let view = AnimationView(name: lottieNameArr[index])
        view.frame = frame
        view.contentMode = .scaleAspectFill
        view.animationSpeed = 1
        return view
    }

    private func setupAnimation(_ tabBarVC: UITabBarController, _ viewController: UIViewController){
        
        if animationView != nil {
            animationView!.stop()
        }
        
    //        1. 获取当前点击的是第几个
        let index = tabBarVC.viewControllers?.index(of: viewController)
        var tabBarSwappableImageViews = [UIImageView]()
        
    //        2.遍历取出所有的 tabBarButton
        for tempView in tabBarVC.tabBar.subviews {
            if tempView.isKind(of: NSClassFromString("UITabBarButton")!) {
                //2.1 继续遍历tabBarButton 找到 UITabBarSwappableImageView 并保存
    //                print("tempView : \(tempView.subviews)" )
                    //从subviews中查找
                    for tempImgV in tempView.subviews {
                        //第一种层级关系 UITabBarButton --> UITabBarSwappableImageView
                        if tempImgV.isKind(of: NSClassFromString("UITabBarSwappableImageView")!) {
                            tabBarSwappableImageViews.append(tempImgV as! UIImageView)
                        }else{
                            //第二种:UITabBarButton --> UIVisualEffectView --> _UIVisualEffectContentView--> UITabBarSwappableImageView
                             let array = tempView.subviews[0].subviews[0].subviews
                            for tempImg in array {
                                if tempImg.isKind(of: NSClassFromString("UITabBarSwappableImageView")!) {
                                    tabBarSwappableImageViews.append(tempImg as! UIImageView)
                                }
                            }
                        }
                    }
                
                
            }
        }
        
        
    //        3. 找到当前的UITabBarButton
        let currentTabBarSwappableImageView = tabBarSwappableImageViews[index!]
        
    //        4. 获取UITabBarButton中的 UITabBarSwappableImageView 并隐藏
        var frame = currentTabBarSwappableImageView.frame
        frame.origin.x = 0
        frame.origin.y = 0
        var animation: AnimationView? = getAnimationViewAtTabBarIndex(index!, frame)
        self.animationView = animation
         self.animationView!.center = currentTabBarSwappableImageView.center
        
        
    //        5. 创建动画 view 加载到 当前的 UITabBarButton 并隐藏 UITabBarSwappableImageView
        currentTabBarSwappableImageView.superview?.addSubview( animation!)
        currentTabBarSwappableImageView.isHidden = true
        
    //        6. 执行动画,动画结束后 显示 UITabBarSwappableImageView 移除 动画 view 并置空
        animation!.play(fromProgress: 0, toProgress: 1) { (finished) in
            currentTabBarSwappableImageView.isHidden = false
            animation!.removeFromSuperview()
             animation = nil
        }
    }
}

UITabBarButton中添加lottie的动画视图时,需要注意的点 tabBar的层级关系变化,有以下两种层级关系

  • 1、旧项目中的tabBar层级关系:从图中可以看出4个tabbar的层级关系是一致的
    旧项目tabbar层级关系
  • 2-1、xcode11.4 新建项目的 tabbar层级关系:除了第一个item的层级关系不一致,其他3个层级关系都是一致的
    新项目的 tabbar层级关系
  • 2-2、新建项目的tabbar还有一种层级关系,不过目前并不是每次都是这样(这种层级关系目前仅出现一次)
- item0
    - UIVisualEffectView
        - _UIVisualEffectContentView
    - UITabBarSwappableImageView
    - UITabBarButtonLabel
- item1
    - UIVisualEffectView
        - _UIVisualEffectContentView
            - UITabBarSwappableImageView
            - UITabBarButtonLabel
- item2
    - UIVisualEffectView
        - _UIVisualEffectContentView
            - UITabBarSwappableImageView
            - UITabBarButtonLabel
- item3
    - UIVisualEffectView
        - _UIVisualEffectContentView
            - UITabBarSwappableImageView
            - UITabBarButtonLabel

完整代码链接 - Lottie_TabBarAnimation

猜你喜欢

转载自blog.csdn.net/lin1109221208/article/details/108386674