如何为标签栏的项目设置动画

Posted

技术标签:

【中文标题】如何为标签栏的项目设置动画【英文标题】:How to animate tab bar's items 【发布时间】:2019-03-29 03:44:33 【问题描述】:

在我的 Swift 应用程序中,我有一个处理 UITabBar 的类。

class CustomTabBar: UITabBar 
    override func awakeFromNib() 
        super.awakeFromNib()
    

当用户点击它们时,我如何为它们设置动画? 我的意思是CGAffine(scaleX: 1.1, y: 1.1) 那么呢?

【问题讨论】:

看看github.com/eggswift/ESTabBarController这应该会有所帮助 【参考方案1】:

首先:

创建自定义UITabBarController,如下:
import UIKit

enum TabbarItemTag: Int 
    case firstViewController = 101
    case secondViewConroller = 102


class CustomTabBarController: UITabBarController 
    var firstTabbarItemImageView: UIImageView!
    var secondTabbarItemImageView: UIImageView!

    override func viewDidLoad() 
        super.viewDidLoad()

        let firstItemView = tabBar.subviews.first!
        firstTabbarItemImageView = firstItemView.subviews.first as? UIImageView
        firstTabbarItemImageView.contentMode = .center

        let secondItemView = self.tabBar.subviews[1]
        self.secondTabbarItemImageView = secondItemView.subviews.first as? UIImageView
        self.secondTabbarItemImageView.contentMode = .center
    

    private func animate(_ imageView: UIImageView) 
        UIView.animate(withDuration: 0.1, animations: 
            imageView.transform = CGAffineTransform(scaleX: 1.25, y: 1.25)
        )  _ in
            UIView.animate(withDuration: 0.25, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 3.0, options: .curveEaseInOut, animations: 
                imageView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
            , completion: nil)
        
    

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 
        guard let tabbarItemTag = TabbarItemTag(rawValue: item.tag) else 
            return
        

        switch tabbarItemTag 
        case .firstViewController:
            animate(firstTabbarItemImageView)
        case .secondViewConroller:
            animate(secondTabbarItemImageView)
        
    

第二:

为每个视图控制器设置tag 的值:tabBarItem

第一个视图控制器:

import UIKit

class FirstViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        tabBarItem.tag = TabbarItemTag.firstViewController.rawValue
    

第二个视图控制器:

import UIKit

class SecondViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()
        tabBarItem.tag = TabbarItemTag.secondViewConroller.rawValue
    

确保您的情节提要已设置好所有内容(如果您正在使用情节提要),仅此而已!

输出:

你可以查看 repo:

https://github.com/AhmadFayyas/Animated-TabbarItem/tree/master

用于演示答案。

【讨论】:

非常感谢!你的帮助很重要。享受 我发现了一个问题,当线程 4 到达 firstTabbarItemImageView.contentMode = .center 时它崩溃了。请问怎么解决 @JackK。你能详细说明一下吗? 好的,我明白了,但我还有另一个问题:函数 didSelect 不起作用,总是返回选中的项目 0。 对于 Swift 4:我必须手动将“标签 101”等添加到情节提要中的每个 tabbaritem,否则它不起作用。【参考方案2】:

由于UITabBarItem 不是UIView 子类,而是NSObject 子类,因此没有直接的方法可以在点击时为项目设置动画。

您要么必须挖掘属于该项目的UIView 并为其设置动画,要么创建一个自定义标签栏。

Here 是挖掘UIView 的一些想法。以及here for example 如何在点击项目时触发。但要非常小心这种方法:

Apple 可能会更改 UITabBar 实现,这可能会破坏这一点。 您可能会干扰 ios 动画并获得奇怪的效果。

顺便说一句,没有必要继承UITabBar。您只需要实现UITabBarDelegate

我实际上建议您坚持使用标准的 UITabBar 行为和蒙皮选项,然后再解决这个问题,或者根本不解决。这样的事情会浪费你的时间,而不会给应用程序增加太多内容。

【讨论】:

你能给我一个教程吗? @JackK。教程最常讨论公共 iOS 功能。所以,我不希望有一个教程。但是我在编辑中添加的链接应该可以帮助您入门。【参考方案3】:

这对我有用:

class MyCustomTabController: UITabBarController 

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) 
        guard let barItemView = item.value(forKey: "view") as? UIView else  return 

        let timeInterval: TimeInterval = 0.3
        let propertyAnimator = UIViewPropertyAnimator(duration: timeInterval, dampingRatio: 0.5) 
            barItemView.transform = CGAffineTransform.identity.scaledBy(x: 0.9, y: 0.9)
        
        propertyAnimator.addAnimations( barItemView.transform = .identity , delayFactor: CGFloat(timeInterval))
        propertyAnimator.startAnimation()
    


【讨论】:

以上是关于如何为标签栏的项目设置动画的主要内容,如果未能解决你的问题,请参考以下文章

UITabBarItem 图标动画

设置标签栏的初始视图控制器

如何为 UILabel 字体更改设置动画?

如何处理标签栏的推送通知,我的标签栏控制器远离根视图控制器

在不动画的 ViewController 上实现一个栏(如标签栏)

如何将“更多”标签栏的编辑视图的导航栏设置为黑色?