在选项卡之间切换时如何创建交叉溶解动画

Posted

技术标签:

【中文标题】在选项卡之间切换时如何创建交叉溶解动画【英文标题】:How to create a cross dissolve animation when switching between tabs 【发布时间】:2019-05-29 03:11:39 【问题描述】:

如何在标签之间切换时执行的标签控制器类中编写简单的交叉溶解动画。

以下是显示此类动画的应用示例。

我对自定义过渡动画还很陌生,我知道它必须在 didSelect 中进行

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 


更新

我似乎有些困惑:

我创建了一个名为 TabBarClass.swift 的新 Swift 文件

我在里面添加了如下代码:

    class MyFadeTransition: NSObject, UIViewControllerAnimatedTransitioning 
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 
            if let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) 
                toVC.view.frame = fromVC.view.frame
                toVC.view.alpha = 0
                fromVC.view.alpha = 1
                transitionContext.containerView.addSubview(fromVC.view)
                transitionContext.containerView.addSubview(toVC.view)

                UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: 
                    toVC.view.alpha = 1
                )  (finished) in
                    transitionContext.completeTransition(finished)
                
            
        

        func animationEnded(_ transitionCompleted: Bool) 
            // no-op
        

        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval 
            return 0.3
        
    


**And in the AppDelegate I added:**

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

        func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? 
            let fade = MyFadeTransition()
            return fade
        

What is the issue?

更新 2

这就是我的 AppDelegate 的编写方式:

import UIKit

@UIApplicationMain


class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?
    var tabBarController: UITabBarController!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 


        let tab = window!.rootViewController as! UITabBarController
        tab.delegate = self


        return true
    



    func applicationWillResignActive(_ application: UIApplication) 
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    

    func applicationDidEnterBackground(_ application: UIApplication) 
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    

    func applicationWillEnterForeground(_ application: UIApplication) 
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    

    func applicationDidBecomeActive(_ application: UIApplication) 
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    

    func applicationWillTerminate(_ application: UIApplication) 
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    



extension AppDelegate: UITabBarControllerDelegate 
    func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? 
        let fade = MyFadeTransition()

        return fade
    

【问题讨论】:

实际上是例如的副本***.com/questions/54842069/…。这是一个不同的动画,但这无关紧要。 【参考方案1】:

利用UITabBarControllerDelegate方法:

func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?

大部分工作都在符合UIViewControllerAnimatedTransitioning的类中。

这是一个交叉淡入淡出两个控制器的实现。

MyFadeTransition.swift:

import UIKit

class MyFadeTransition: NSObject, UIViewControllerAnimatedTransitioning 
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) 
        if let fromVC = transitionContext.viewController(forKey: .from), let toVC = transitionContext.viewController(forKey: .to) 
            toVC.view.frame = fromVC.view.frame
            toVC.view.alpha = 0
            fromVC.view.alpha = 1
            transitionContext.containerView.addSubview(fromVC.view)
            transitionContext.containerView.addSubview(toVC.view)

            UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: 
                toVC.view.alpha = 1
            )  (finished) in
                transitionContext.completeTransition(finished)
            
        
    

    func animationEnded(_ transitionCompleted: Bool) 
        // no-op
    

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval 
        return 0.3
    

您的代码中的某些内容必须是标签栏控制器的delegate。设置它,然后在该类中实现委托方法。

func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? 
    let fade = MyFadeTransition()
    return fade

请注意,同样的MyFadeTransition 类可以与UINavigationController 一起使用。 UINavigationControllerDelegate 具有相同的基本方法,因此您可以为标签栏控制器和导航控制器重用转换类。

假设您的标签栏控制器是您应用的根视图控制器,您可以将以下代码添加到您的 AppDelegate 的 didFinishLaunchingWithOptions

let tab = window!.rootViewController as! UITabBarController
tab.delegate = self

然后添加:

extension AppDelegate: UITabBarControllerDelegate 
    func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? 
        let fade = MyFadeTransition()

        return fade
    

到 AppDelegate.swift。

【讨论】:

感谢您的帮助 rmaddy,我有点困惑我正在使用情节提要,所以我尝试将 MyFadeTransition 类分配给选项卡视图控制器,但它没有显示 您没有将MyFadeTransition 类添加到选项卡控制器。只需将该类添加到您的项目中。您需要一些类作为选项卡视图控制器的delegate。这可以是AppDelegate 类或任何其他适当的类。无论您选择哪个类,将该类设置为标签栏控制器的delegate 属性。然后将委托方法(如上所示)放入该类中。 请查看我发布的更新,我不明白我做错了什么,对于委托,我将上述(最后)代码添加到 AppDelegate 文件并将类添加到新的单独视图控制器。但是还是不行 不要添加TabBarClass.swift。添加MyFadeTransition.swift。您唯一缺少的部分是将标签栏控制器的delegate 属性设置为您的AppDelegate。请参阅我的更新答案。 我不断收到扩展 AppDelegate 的 'AppDelegate' to protocol 'UITabBarControllerDelegate'Invalid redeclaration of 'tabBarController(_:animationControllerForTransitionFrom:to:)' 的冗余一致性错误。我像建议的那样把它放在 AppDelegate.swift 中

以上是关于在选项卡之间切换时如何创建交叉溶解动画的主要内容,如果未能解决你的问题,请参考以下文章

TabView 在为 SwiftUI 设置动画的选项卡之间切换

mfc 选项卡控制切换选项卡

在选项卡之间切换时获取核心数据

jQuery - 带有视频的标签...当我在标签之间切换时如何让视频停止播放?

PyQt5 QTabWidget:如何在类和同一窗口中包含的选项卡之间切换?

使用按钮在Access中的选项卡之间切换