简介
正常情况下,我们点击tabbar都只有一个变色效果,但有时候,如果我们想给它添加一个点击动画,该如何做呢? 以下是两种方法:
方法一
通过tabBar: didSelectItem:
代理方法接收每次点击的item,对每个item都绑定动画效果,弊端是获取到的是整个item,图标和标题都会一起动。
方法二
是自定一个方法单独获取tabbar item的image和label,可自定只对某个item绑定动画,并且可设定单独image的动画。
效果图
第二种方法:只对image执行动画
1、带重力效果的弹跳
后4个是第一种方法
2、先放大,再缩小
3、Z轴旋转
4、Y轴位移
5、放大并保持
代码实现
获取要执行动画的Item
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| @interface MainTabbarVC ()<UITabBarControllerDelegate> @property (nonatomic,assign) NSInteger indexFlag; @end
-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{ NSInteger index = [self.tabBar.items indexOfObject:item]; if (index != self.indexFlag) { NSMutableArray *arry = [NSMutableArray array]; for (UIView *btn in self.tabBar.subviews) { if ([btn isKindOfClass:NSClassFromString(@"UITabBarButton")]) { [arry addObject:btn]; } }
self.indexFlag = index; } }
- (void)tabBarImageAnimation { for (UIControl *tabBarButton in self.tabBar.subviews) { if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) { for (UIControl *tabBarButtonLabel in tabBarButton.subviews) { if ([tabBarButtonLabel isKindOfClass:NSClassFromString(@"UITabBarButtonLabel")]) { UILabel *label = (UILabel *)tabBarButtonLabel; if (![label.text isEqualToString:@"tab1"] && ![label.text isEqualToString:@"tab2"] && ![label.text isEqualToString:@"tab3"] && ![label.text isEqualToString:@"tab4"]) { for (UIView *imageView in tabBarButton.subviews) { if ([imageView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) { } } } } } } } }
|
第二种方法的用法比较灵活,比如可以在TabbarVC里设上面tabBarImageAnimation
方法的通知Observer,在需要执行动画的地方比如打开某VC时在该VC的viewDidAppear
里post通知即可。
动画代码
1、带重力效果的弹跳
1 2 3 4 5 6
| CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
animation.values = @[@0.0, @-4.15, @-7.26, @-9.34, @-10.37, @-9.34, @-7.26, @-4.15, @0.0, @2.0, @-2.9, @-4.94, @-6.11, @-6.42, @-5.86, @-4.44, @-2.16, @0.0]; animation.duration = 0.8; animation.beginTime = CACurrentMediaTime() + 1; [imageView.layer addAnimation:animation forKey:nil];
|
2、先放大,再缩小
1 2 3 4 5 6 7 8 9 10
| CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.duration = 0.2; animation.repeatCount = 1; animation.autoreverses = YES; animation.fromValue = [NSNumber numberWithFloat:0.7]; animation.toValue = [NSNumber numberWithFloat:1.3]; [[arry[index] layer] addAnimation:animation forKey:nil];
|
3、Z轴旋转
1 2 3 4 5 6 7 8 9 10
| CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.duration = 0.2; animation.repeatCount = 1; animation.removedOnCompletion = YES; animation.fromValue = [NSNumber numberWithFloat:0]; animation.toValue = [NSNumber numberWithFloat:M_PI]; [[arry[index] layer] addAnimation:animation forKey:nil];
|
4、Y轴位移
1 2 3 4 5 6 7 8 9 10
| CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.duration = 0.2; animation.repeatCount = 1; animation.removedOnCompletion = YES; animation.fromValue = [NSNumber numberWithFloat:0]; animation.toValue = [NSNumber numberWithFloat:-10]; [[arry[index] layer] addAnimation:animation forKey:nil];
|
5、放大并保持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.duration = 0.2; animation.repeatCount = 1; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; animation.fromValue = [NSNumber numberWithFloat:1.0]; animation.toValue = [NSNumber numberWithFloat:1.15]; [[arry[index] layer] addAnimation:animation forKey:nil];
for (int i = 0; i<arry.count; i++) { if (i != index) { [[arry[i] layer] removeAllAnimations]; } }
|
此外,如果想定制其他动画效果,还可以从下面属性里自己定制动画