彩色TabBar切换动画实现

彩色TabBar切换动画实现

无意间看到一个彩色TabBar切换的设计图,感觉很不错,有空就把他实现了。 环境信息 Mac OS X 10.10.4 Xcode 6.4 iOS 8.4 效果图:

源码下载地址: https://github.com/saitjr/TColorfulTabBar.git

一、实现分析

看到这个彩色切换效果的时候,我第一个反应就是在TabBar上有一个彩色的View,然后每个色块的显示都是通过mask来显示的。最终,我的具体实现也是根据这个思路来的。

1. 设计思想

为了减少侵入性(耦合),我采取的是继承UITabBar来实现,所以要集成的时候,只需要将系统的TabBar换成我写的TColorfulTabBar就可以了。

2. 视图层级图

二、效果实现

1. 添加彩色视图colorfulView

TColorfulTabBar.m

- (void)setupColorView {

    // 初始化彩色视图,并将它加在tabbar上
    UIView *colorView = [[UIView alloc] initWithFrame:self.bounds];
    [self addSubview:colorView];
    self.colorfulView = colorView;

    // 彩色视图的五种颜色,这是一个UIColor数组,
    NSArray *colors = self.itemColors;
    CGFloat itemWidth = self.bounds.size.width / self.itemCount;

    for (int i = 0; i < self.itemCount; i ++) {

        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(itemWidth * i, 0, itemWidth, self.bounds.size.height)];
        view.backgroundColor = colors[i];
        [self.colorfulView addSubview:view];
    }
}

2. 添加彩色视图的遮罩colorfulMaskView

之所以这里的遮罩使用的是UIView而不是CAShapeLayer或者CALayer,原因如下:

  • 遮罩是矩形,没必要使用路径,所以不用CAShapeLayer
  • 通过设计图可以看到,在位移动画之前,有一个遮罩单向变宽(向左或向右)的效果。如果使用CALayer,那么改变bounds的时候,是双向改变,想要单向就必须加锚点,太麻烦
  • 如果使用UIView,那么向右变宽只需要x不变,width变长就行;向左变宽只需要x-value,width+value就行,要方便的多
  • 最后一点就是在做动画的时候,Layer要用到CABaseAnimation,然而UIView使用UIView的Animation就行

在设置遮罩的时候,将colorfulMaskView的layer设置为colorfulView的mask就可以了。 代码实现如下: TColorfulTabBar.m

- (void)setupMaskLayer {

    // 获取每个item的宽度
    CGFloat itemWidth = self.bounds.size.width / self.itemCount;

    // 初始化colorMaskView,并将colorMaskView的layer设置成彩色视图的遮罩
    UIView *colorMaskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, itemWidth, self.bounds.size.height)];
    colorMaskView.backgroundColor = [UIColor blackColor];
    self.colorfulMaskView = colorMaskView;
    self.colorfulView.layer.mask = self.colorfulMaskView.layer;
}

3. 设置代理,获取当前点击的下标

UITabBar并没有获取点击下标的接口,但是UITabBarDelegate有,这个协议默认被UITabBarController遵守。为了降低耦合性,采用UITabBar自己获取下标,所以,需要UITabBar自己实现自己的delegate。 值得注意的是,不能在UITabBar的初始化方法中去设置self.delegate = self,因为即使设置了,也会被UITabBarController覆盖。最终解决方案是当UITabBar加载到父视图上是,在修改delegate为self。

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    self.delegate = self;
}

因为每次的移动位置与方向都和上次的下标与这次的下标有关,所以需要使用到属性来记录这两个下标的值。 - (void)tabBar:(UITabBar )tabBar didSelectItem:(UITabBarItem )item {

    NSInteger index = [self.items indexOfObject:item];
    self.fromeIndex = self.toIndex;
    self.toIndex = index;
    // 拿到下标以后执行动画
    [self animation];
}

4. 移动遮罩,显示不同的色块

在做动画的时候,需要考虑到效果的平滑性。整个动画有两个动画组成,一个是宽度放大的动画,一个是缩小到原来大小和位移动画。整个动画是EaseInOut的效果,所以拆开来看,就应该第一个动画EaseIn,第二个动画EaseOut。 一图胜千言:

- (void)animation {

    CGFloat itemWidth = self.bounds.size.width / self.itemCount;
    // 为了效果看起来更平滑,所以根据两次下标的差值来计算需要放大的距离
    CGFloat extraWidth = ABS(self.toIndex - self.fromeIndex) * itemWidth / 4;

    // 放大的大小
    CGRect scaleFrame = CGRectMake(self.colorfulMaskView.x, 0, itemWidth + extraWidth, self.bounds.size.height);
    // 最终大的大小与位置
    CGRect toFrame = CGRectMake(self.toIndex * itemWidth, 0, itemWidth, self.bounds.size.height);

    // 如果是向左移动,那修改x轴的坐标
    if (self.fromeIndex > self.toIndex) {

        scaleFrame = CGRectMake(self.colorfulMaskView.x - extraWidth, 0, itemWidth + extraWidth, self.bounds.size.height);
    }

    // 两个动画加起来是一个EaseInOut的效果,所以第一个动画就应该是EaseIn,第二个动画是EaseOut
    // 先进行放大
    [UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{

        self.colorfulMaskView.frame = scaleFrame;
    } completion:^(BOOL finished) {

        // 再进行缩小和位移
        [UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{

            self.colorfulMaskView.frame = toFrame;
        } completion:NULL];
    }];
}

原文:http://www.brighttj.com/ios/ios-colorful-tabbar-implement.html

本文出处刚刚在线:http://www.superqq.com/blog/2015/08/11/color-tabbar-switch-animation/

时间: 2024-11-04 11:07:47

彩色TabBar切换动画实现的相关文章

【iOS】彩色TabBar切换动画实现

无意间看到一个彩色TabBar切换的设计图,感觉很不错,有空就把他实现了. 环境信息 Mac OS X 10.10.4 Xcode 6.4 iOS 8.4 效果图: 效果图 源码下载地址: https://github.com/saitjr/STColorfulTabBar.git 正文 一.实现分析 看到这个彩色切换效果的时候,我第一个反应就是在TabBar上有一个彩色的View,然后每个色块的显示都是通过mask来显示的.最终,我的具体实现也是根据这个思路来的. 1. 设计思想 为了减少侵入

viewPager的切换动画

今天在看苏州通的代码,里面有个引导的代码,涉及到viewPager的切换动画: DepthPageTransformer : 1 package com.soyoungboy.guide; 2 import android.annotation.TargetApi; 3 import android.os.Build; 4 import android.support.v4.view.ViewPager; 5 import android.view.View; 6 /** 7 * 8 * @Cl

Android Activity的切换动画(overridePendingTransition)

overridePendingTransition 1.平时Activity的切换是就是从中间弹出来,然后遮盖住之前的Activity.这种效果看到很多后就想给他换成其他的效果,如: 要显示的Acitvity从左边往右的平移进入,被遮盖的Activity从左往右的平移划出. 在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,从Android2.0开始在Activity增加了一个方法: pub

iOS 自定义页面的切换动画与交互动画

在iOS7之前,开发者为了寻求自定义Navigation Controller的Push/Pop动画,只能受限于子类化一个UINavigationController,或是用自定义的动画去覆盖它.但是随着iOS7的到来,Apple针对开发者推出了新的工具,以更灵活地方式管理UIViewController切换. 自定义导航栏的Push/Pop动画 为了在基于UINavigationController下做自定义的动画切换,先建立一个简单的工程,这个工程的rootViewController是一个

activity切换动画和页面切换动画

Activity切换动画 要实现Activity切换动画需要靠overridePendingTransition来实现,里面有两个参数分别是进入Activity时的动画和离开Activity时的动画. 需要注意的是必须在StartActivity()或finish()之后立即调用 比如在MainActivity中有一个Button,点击Button后跳转到OtherActivity中代码如下: Intent intent = new Intent(this, OtherActivity.clas

iOS项目开发实战——实现视图切换动画

不同界面或者说不同视图之间进行切换是应用程序的一种最常见的动态效果,无论是哪一种平台的项目开发,默认的视图切换往往是十分单调的,没有任何动画的,界面的切换也是非常的突兀.如果说使用动画效果使界面能够活跃起来,那么你的App将会非常动感.这里将实现视图切换过程中的动画效果.具体实现如下: (1)本次试验将拖入2张图片,不直接放到View Controller中,而是在代码中动态加载.拖到Main.storyboard中后目录结构如下: . (2)实现图片与代码Outlet绑定: @IBOutlet

Android中Activity切换时共享视图元素的切换动画(4.x兼容方案)

同时发布在我的博客 点此进入 开始 上一篇讲了使用 Google 的 AppCompat-v7 来实现 Activity 切换时实现共享视图元素的切换动画.这一篇介绍两个可以兼容 4.x 的两个第三方方案. 上一篇:Android中Activity切换时共享视图元素的切换动画(5.0以上) 方案一:PreLollipopTransition 首先在 build.gradle 配置文件添加这个库依赖 dependencies { compile 'com.kogitune:pre-lollipop

Activity 切换 动画

overridePendingTransition的简介 1 Activity的切换动画指的是从一个activity跳转到另外一个activity时的动画. 它包括两个部分:一部分是第一个activity退出时的动画:另外一部分时第二个activity进入时的动画:在Android的2.0版本之后,有了一个函数来帮我们实现这个动画.这个函数就是overridePendingTransition 这个函数有两个参数,一个参数是第一个activity进入时的动画,另外一个参数则是第二个activit

Activity 设置切换动画

extends://blog.csdn.net/luohaowang320/article/details/42124225 | http://blog.csdn.net/xuewater/article/details/36398803 最近写项目的时候需要用到大量的activity切换动画,于是就用了考虑到了theme中引用style来实现,但是竟然无效,很是郁闷,几经波折,找到了原因,原来是style里面设置了android:windowIsTranslucent这个属性,代码如下: <s