【问题标题】:Animate UIViewController content while navigating using TabBar使用 TabBar 导航时为 UIViewController 内容设置动画
【发布时间】:2020-04-19 17:51:07
【问题描述】:

我正在尝试复制从一个标签栏 VC 导航到另一个标签栏 VC 时 Google Drive(iOS 版本)的动画(见下文):

我目前在选择标签栏项目时可以访问 fromViewtoView,因此我可以使用 UIView.animate() 为这两个视图设置动画:

class MyCustomTabBarVC: UITabBarController {


    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}



extension MyCustomTabBarVC: UITabBarControllerDelegate  {
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

        guard let fromView = selectedViewController?.view, let toView = viewController.view else {
          return false
        }


        if fromView != toView {
            fromView.alpha = 1
            toView.alpha = 0.8

            UIView.animate(withDuration: 0.5, delay: 0.0, options: [.curveEaseInOut], animations: {
                fromView.alpha = 0

            }, completion: { (_) in
                UIView.animate(withDuration: 0.5, delay: 0.0, options: [.curveEaseInOut], animations: {
                    toView.alpha = 1
                })
            })

        }

        return true
    }
}

问题是我无法理解在 Google Drive 的情况下使用什么类型的动画(或动画链)。

我在上面代码中使用的动画不会有相同的结果。任何对动画有更好理解的人都可以帮忙吗? :)

【问题讨论】:

    标签: ios swift animation


    【解决方案1】:

    嗯,我想说,首先他们使用更快的动画(更短的持续时间)并且它们同时发生。此外,他们正在为给定视图的 alphascale 设置动画。

    我会使用这样的东西:

    ...
        // prepare view
        toView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
        toView.alpha = 0
    
        // Animate
        UIView.animate(withDuration: 0.3, delay: 0.0, options: [.curveEaseInOut], 
        animations: {
           fromView.alpha = 0
           fromView.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
    
           toView.transform = .identity
           toView.alpha = 1
    
        }, completion: nil)
    

    好点了吗?

    编辑:

    正如我们在 cmets 中讨论的另一个解决方案 - 为了获得更好的方法来为子视图设置动画,您可以对这些 viewController 进行类型转换。 不要忘记,如果您嵌入了例如 UINavigationControllers,您必须首先将类型转换为该类! 我试过了,效果很好:

    extension MyCustomTabBarVC: UITabBarControllerDelegate  {
    
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    
        // Presented View Controller which should fade out
        if let selectedNC = selectedViewController as? UINavigationController {
            if let myFirstVC = selectedNC.viewControllers.first as? MyFirstViewController {
                // animate fade out
            } else if let mySecondVC = selectedNC.viewControllers.first as? MySecondViewController {
                // animate fade out
            }
        }
    
        // View Controllers which should be selected
        if let navigationController = viewController as? UINavigationController {
    
            if let firstC = navigationController.viewControllers.first as? MyFirstViewController {
               // animate fade in
            } else if let firstC = navigationController.viewControllers.first as? MySecondViewController {
                // animate fade in
            }
        }
    
        return true
    }
    

    }

    如果没有导航控制器,您可以像这样简单地进行类型转换:

    ...
        if let myFirstVC = selectedViewController as? MyFirstViewController {
          // animate fade out
        }
     ...
    

    【讨论】:

    • 实际上这是正确的方法,但我稍微使用了这些值。另外“toView.alpha”我从 0.85 开始,因为 0 值导致问题(白光快速闪烁)。知道如何选择不制作动画的视图元素(例如 Google Drive 应用中的搜索字段)吗?
    • 哦,快速闪现可能与您正在为 ViewController 的整个视图制作动画这一事实有关。如果您首先键入强制转换这些视图控制器(例如,guard let yourVC = selectedViewController as? YourViewController ...),也许您可​​以解决这个问题+您需要从动画中排除一些子视图。然后您可以访问给定视图控制器的各个子视图及其功能。因此,您可以在视图控制器中准备这些动画,然后调用类似“yourVC.animateSubviews()”之类的东西。
    • 这实际上可能是解决方案!让我试试这个,我会回来的!
    • 我正在尝试将 shouldSelect 视图控制器强制转换为我的视图控制器之一,但我失败了。基本上我使用 let selectedIndex = tabBarController.viewControllers?.firstIndex(of viewController) 获得 selectedIndex!然后我检查索引的编号。说 index 0 是我的 HomeVC,然后我这样做: if selectedIndex == 0 { if let vc = viewController as? HomeVC {打印(“成功”)}否则{打印(“失败”)}。而且我总是失败! :)
    • @christostsang 我已经用我将用来键入这些视图控制器的代码编辑了我的原始答案。我认为您不需要使用索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 2019-05-15
    • 2017-07-03
    • 1970-01-01
    相关资源
    最近更新 更多