iOS UITabbar图标点击动画效果实现

3,484 阅读3分钟

iOS UITabbar图标点击动画效果实现


简介

正常情况下,我们点击tabbar都只有一个变色效果,但有时候,如果我们想给它添加一个点击动画,该如何做呢? 以下是两种方法:

方法一

通过tabBar: didSelectItem:代理方法接收每次点击的item,对每个item都绑定动画效果,弊端是获取到的是整个item,图标和标题都会一起动。

方法二

是自定一个方法单独获取tabbar item的image和label,可自定只对某个item绑定动画,并且可设定单独image的动画。

效果图

第二种方法:只对image执行动画

1、带重力效果的弹跳

后4个是第一种方法

2、先放大,再缩小

3、Z轴旋转

4、Y轴位移

5、放大并保持

代码实现

获取要执行动画的Item

@interface MainTabbarVC ()<UITabBarControllerDelegate>
@property (nonatomic,assign) NSInteger  indexFlag;&emsp;&emsp;//记录上一次点击tabbar,使用时,记得先在init或viewDidLoad里 初始化 = 0
@end

//第一种方法:通过接收点击事件对每个tabbar item的点击都执行动画
-(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];
            }
        }
        //添加动画
&emsp;&emsp;&emsp;&emsp; //---将下面的动画代码块拷贝到此并修改最后一行addAnimation的layer对象即可---

        self.indexFlag = index;
    }
}

//第二种方法:只想对某一个item的点击执行动画,且只有图片动,文字不动。并且其余图标的点击不带动画
- (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;
                    //"tab1"到"tab4"分别是不打算执行动画的tabbar item的标题名称
                    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")]) {
                                //添加动画
                                //---将下面的动画代码块拷贝到此并修改最后一行addAnimation的layer对象即可---
                            }
                        }
                    }
                }
            }
        }
    }
}

第二种方法的用法比较灵活,比如可以在TabbarVC里设上面tabBarImageAnimation方法的通知Observer,在需要执行动画的地方比如打开某VC时在该VC的viewDidAppear里post通知即可。

动画代码

1、带重力效果的弹跳

CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
//通过初中物理重力公式计算出的位移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、先放大,再缩小

//放大效果,并回到原位
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轴旋转

//z轴旋转180度
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轴位移

//向上移动
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、放大并保持

//放大效果
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];
//移除其他tabbar的动画
for (int i = 0; i<arry.count; i++) {
    if (i != index) {
        [[arry[i] layer] removeAllAnimations];
    }
}

此外,如果想定制其他动画效果,还可以从下面属性里自己定制动画