iPhone 版 Skype 应用程序使用动画 TabBar 图标。例如,在登录过程中,最右侧的选项卡图标显示循环箭头。在调用“呼叫”选项卡图标时轻轻闪烁,这显然是通过动画完成的。
我想知道如何为标签栏项目的图标设置动画。
在我的特殊情况下,当用户按下“收藏夹”按钮时,它会跳转到“收藏夹”标签栏项目。我已经实现了跳跃动画,但是我希望相应的标签栏图标在动画结束时闪烁,给它带来完整的感觉。
关于我应该研究的方向有什么建议吗?
提前致谢。
iPhone 版 Skype 应用程序使用动画 TabBar 图标。例如,在登录过程中,最右侧的选项卡图标显示循环箭头。在调用“呼叫”选项卡图标时轻轻闪烁,这显然是通过动画完成的。
我想知道如何为标签栏项目的图标设置动画。
在我的特殊情况下,当用户按下“收藏夹”按钮时,它会跳转到“收藏夹”标签栏项目。我已经实现了跳跃动画,但是我希望相应的标签栏图标在动画结束时闪烁,给它带来完整的感觉。
关于我应该研究的方向有什么建议吗?
提前致谢。
我很惊讶解决方案如此简单!
将方法添加到您的 Application Delegate 类 .m 文件(或管理您的 UITabBar 的任何其他类),其中包含以下例程:
addSubview:
。frame.origin.x
值,将 Image 放在要设置动画的选项卡 bat 项目的正上方。很简单,你不这么认为吗?
您可以在需要为标签栏项目设置动画的任何地方调用 UIApplicationDelegate 实例上的此方法。
同样重要的是要注意,您可以点击 imageView 来选择标签栏项目,就好像标签栏上没有图像一样。如果你知道的话,你可以在这里做很多有趣的结论......
我找到了解决这个问题的更好方法。添加自定义图像视图不是更好的方法,因为在 iOS 10.0 及更高版本中,更改方向后,图标框架和文本位置发生了变化。您只需要设置 UITabBarController 的类并输入以下代码。
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
let index = self.tabBar.items?.index(of: item)
let subView = tabBar.subviews[index!+1].subviews.first as! UIImageView
self.performSpringAnimation(imgView: subView)
}
//func to perform spring animation on imageview
func performSpringAnimation(imgView: UIImageView) {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
imgView.transform = CGAffineTransform.init(scaleX: 1.4, y: 1.4)
//reducing the size
UIView.animate(withDuration: 0.5, delay: 0.2, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
imgView.transform = CGAffineTransform.init(scaleX: 1, y: 1)
}) { (flag) in
}
}) { (flag) in
}
}
请记住,UITabBar 中子视图的顺序可能是无序的,因此使用索引从中访问正确的项目可能无法正常工作,正如Naresh 回答所建议的那样。看看这篇文章UITabBar subviews change order
我找到的解决方案是首先过滤和排序视图,然后使用 tabBarItem 的正确索引访问它。
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
let orderedTabBarItemViews: [UIView] = {
let interactionViews = tabBar.subviews.filter({ $0 is UIControl })
return interactionViews.sorted(by: { $0.frame.minX < $1.frame.minX })
}()
guard
let index = tabBar.items?.firstIndex(of: item),
let subview = orderedTabBarItemViews[index].subviews.first
else {
return
}
performSpringAnimation(for: subview)
}
func performSpringAnimation(for view: UIView) {
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
view.transform = CGAffineTransform(scaleX: 1.25, y: 1.25)
UIView.animate(withDuration: 0.5, delay: 0.2, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
view.transform = CGAffineTransform(scaleX: 1, y: 1)
}, completion: nil)
}, completion: nil)
}
您可以通过获取其视图为标签栏图标设置动画,然后为 UIView 执行任何您喜欢的动画。下面是一个简单的比例变换示例,加油!
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem){
var tabBarView: [UIView] = []
for i in tabBar.subviews {
if i.isKind(of: NSClassFromString("UITabBarButton")! ) {
tabBarView.append(i)
}
}
if !tabBarView.isEmpty {
UIView.animate(withDuration: 0.15, animations: {
tabBarView[item.tag].transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
}, completion: { _ in
UIView.animate(withDuration: 0.15) {
tabBarView[item.tag].transform = CGAffineTransform.identity
}
})
}
}
ps:请按顺序为每个UITabBarItem分配标签
子视图UIImageView
中的索引不能保证为拳头。
UIImageView 的索引在相关子视图中不保证为第一。
所以最好通过类类型访问它,并检查索引是否越界。
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
guard let idx = tabBar.items?.firstIndex(of: item),
tabBar.subviews.count > idx + 1,
let imageView = tabBar.subviews[idx + 1].subviews.compactMap({ $0 as? UIImageView }).first else {
return
}
imageView.layer.add(bounceAnimation, forKey: nil)
}
这是一个基本的弹跳动画示例,使用CAKeyframeAnimation
:
private var bounceAnimation: CAKeyframeAnimation = {
let bounceAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
bounceAnimation.values = [1.0, 1.3, 0.9, 1.0]
bounceAnimation.duration = TimeInterval(0.3)
bounceAnimation.calculationMode = CAAnimationCalculationMode.cubic
return bounceAnimation
}()
在目标c中为标签栏项目设置动画的简单方法
在您的标签栏控制器类中
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
UIVisualEffectView *viv = tabBar.subviews[item.tag].subviews.firstObject;
UIImageView *img = viv.contentView.subviews.firstObject;
// If UIImageView not get use this code
// UIImageView *img = tabBar.subviews[item.tag].subviews.lastObject;
[self shakeAnimation:img];
//[self bounceAnimation:img];
}
- (void)shakeAnimation:(UIImageView *)img
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
[animation setDuration:0.05];
[animation setRepeatCount:2];
[animation setAutoreverses:YES];
[animation setFromValue:[NSValue valueWithCGPoint: CGPointMake([img center].x - 10.0f, [img center].y)]];
[animation setToValue:[NSValue valueWithCGPoint: CGPointMake([img center].x + 10.0f, [img center].y)]];
[[img layer] addAnimation:animation forKey:@"position"];
}
- (void)bounceAnimation:(UIImageView *)img
{
img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);
[UIView animateWithDuration:0.3/1.5 animations:^{
img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3/2 animations:^{
img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3/2 animations:^{
img.transform = CGAffineTransformIdentity;
}];
}];
}];
}
我还没有这样做,但我只是尝试构建一个 CAAnimation,例如使用 CABasicAnimation 并将其添加到您想要动画的 UITabBarItem 中。
有关如何设置 CABasicAnimation 的详细信息,请参阅核心动画编程指南:http: //developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/AnimatingLayers.html#//apple_ref/doc/ uid/TP40006085-SW1