在我的Swift应用中,我有一个类来处理UITabBar。
UITabBar
class CustomTabBar: UITabBar { override func awakeFromNib() { super.awakeFromNib() } }
当用户点击项目时,我如何设置项目的动画?我的意思是CGAffine(scaleX: 1.1, y: 1.1)那么我如何可以动画标签栏的项目?
CGAffine(scaleX: 1.1, y: 1.1)
vngu2lb81#
创建自定义UITabBarController,如下所示:
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) } } }
为每个视图控制器的tabBarItem设置tag值:第一个ViewController:
tabBarItem
tag
import UIKit class FirstViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() tabBarItem.tag = TabbarItemTag.firstViewController.rawValue } }
第二个ViewController:
import UIKit class SecondViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() tabBarItem.tag = TabbarItemTag.secondViewConroller.rawValue } }
确保一切都已设置与您的故事板(如果您正在使用一个),这是差不多了!
输出:
你可以查看repo:https://github.com/AhmadFayyas/Animated-TabbarItem/tree/master来证明答案。
dfty9e192#
这对我来说是个窍门:
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() } }
f8rj6qna3#
因为UITabBarItem不是UIView子类,而是NSObject子类,所以没有直接的方法来在点击项目时设置动画。你要么要挖掘属于该项目的UIView并将其动画化,要么创建一个自定义标签栏。Here是挖掘UIView的一些想法。以及here for example如何在项目被点击时触发。但是要非常小心地使用这种方法:
UITabBarItem
UIView
NSObject
顺便说一下,没有必要子类化UITabBar。实现UITabBarDelegate就是你所需要的。实际上我会建议你坚持使用标准的UITabBar行为和皮肤选项,然后再解决这个问题,或者根本不解决。像这样的事情会浪费你的时间,而不会给应用程序增加太多。
UITabBarDelegate
enyaitl34#
这里是更优化的解决方案与任何数量的控制器。查看代码中的注解以更好地理解逻辑。
class TabBarViewController: UITabBarController, UITabBarControllerDelegate { // MARK: - UI Properties private var firstVC = UIViewController() private var secondVC = UIViewController() private let thirdVC = UIViewController() private var tabBarImageViews: [UIImageView] = [] public lazy var tabBarHeight = tabBarController?.tabBar.frame.size.height // Tag to set tabBar items and images to animate private let startTagValue = 100 // MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() self.delegate = self setControllers() // Set images to animate possibility let tabBarSubviews = tabBar.subviews var imageViewTag = startTagValue for subview in tabBarSubviews { if let imageView = subview.subviews.first as? UIImageView { imageView.contentMode = .center imageView.tag = imageViewTag imageViewTag += 1 tabBarImageViews.append(imageView) } } } // MARK: - Methods private func setControllers() { let controllers = [firstVC, secondVC, thirdVC] viewControllers = controllers.map { UINavigationController(rootViewController: $0)} // Set tag to each tabBarItem to know what imageView to animate var controllerItemTag = startTagValue controllers.forEach { controller in controller.tabBarItem.tag = controllerItemTag controllerItemTag += 1 } } private func animate(_ imageView: UIImageView) { UIView.animate(withDuration: 0.1, animations: { imageView.transform = CGAffineTransform(scaleX: 1.15, y: 1.15) }) { _ 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) } } // MARK: - Delegate Methods override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { if let imageToAnimate = tabBarImageViews.first(where: { $0.tag == item.tag }) { animate(imageToAnimate) } }
}
4条答案
按热度按时间vngu2lb81#
首先:
创建自定义
UITabBarController
,如下所示:秒:
为每个视图控制器的
tabBarItem
设置tag
值:第一个ViewController:
第二个ViewController:
确保一切都已设置与您的故事板(如果您正在使用一个),这是差不多了!
输出:
你可以查看repo:
https://github.com/AhmadFayyas/Animated-TabbarItem/tree/master
来证明答案。
dfty9e192#
这对我来说是个窍门:
f8rj6qna3#
因为
UITabBarItem
不是UIView
子类,而是NSObject
子类,所以没有直接的方法来在点击项目时设置动画。你要么要挖掘属于该项目的
UIView
并将其动画化,要么创建一个自定义标签栏。Here是挖掘
UIView
的一些想法。以及here for example如何在项目被点击时触发。但是要非常小心地使用这种方法:UITabBar
的实现,这可能会打破这一点。顺便说一下,没有必要子类化
UITabBar
。实现UITabBarDelegate
就是你所需要的。实际上我会建议你坚持使用标准的
UITabBar
行为和皮肤选项,然后再解决这个问题,或者根本不解决。像这样的事情会浪费你的时间,而不会给应用程序增加太多。enyaitl34#
这里是更优化的解决方案与任何数量的控制器。查看代码中的注解以更好地理解逻辑。
}