【iOS】彩色TabBar切换动画实现
无意间看到一个彩色TabBar切换的设计图,感觉很不错,有空就把他实现了。
环境信息
Mac OS X 10.10.4
Xcode 6.4
iOS 8.4
效果图:
效果图
源码下载地址:
正文
一、实现分析
看到这个彩色切换效果的时候,我第一个反应就是在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要用到CABasicAnimation(
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];
}];
}
【iOS】彩色TabBar切换动画实现的更多相关文章
- IOS自定义场景切换动画。
IOS中我们可以通过Storyborad以及segue来实现我们自己的场景切换动画,新建项目使用Single View Application模板并取名为MyCustomSegue. 使用storyb ...
- iOS 界面翻转切换动画
[UIView beginAnimations:nil context:NULL]; [UIView setAnimationCurve:UIViewAnimationCurveLinear]; [ ...
- Android的Activity切换动画特效库SwitchLayout,视图切换动画库,媲美IOS
由于看了IOS上面很多开发者开发的APP的视图界面切换动画体验非常好,这些都是IOS自带的,但是Android的Activity等视图切换动画并没有提供原生的,所以特此写了一个可以媲美IOS视图切换动 ...
- iOS页面切换动画实现方式。
iOS页面切换动画实现方式. 1.使用UIView animateWithDuration:animations:completion方法 Java代码 [UIView animateWithDura ...
- IOS 视图切换动画
我在网上找到的这个小方法,被我举一反三使用的屡试不爽.比如用在,当视图需要执行某一方法跳转到新的一个UIView上,从底层渐变浮到最上层.就是一个不错的视觉效果或者当需要类似keyboard的效果从底 ...
- jQuery Mobile 连接外部连接或切换动画
jQuery Mobile不同网页之间的跳转问题 jQuery Mobile,一个新的手机终端脚本开发库,从名字可以看出,它是基于jQuery:目前支持很多种手机设备,包括IOS/Android/Bl ...
- IOS开发系列 --- 核心动画
原始地址:http://www.cnblogs.com/kenshincui/p/3972100.html 概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥i ...
- ios图层转场动画
动画类型 CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果.iOS比Mac OS X的转场动画效果少一点 UINavigationController就是通过CA ...
- Swift:超炫的View Controller切换动画
匿名社交应用Secret的开发者开发了一款叫做Ping的应用,用户可以他们感兴趣的话题的推送. Ping有一个很炫的东西,就是主界面和之间切换的动画做的非常的好.每次看到一个非常炫的动画,都不由得会想 ...
随机推荐
- php对xml文件进行CURD操作
XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...
- MVC中Json的使用:Controller中Json的处理
一.当查询得到的数据符合前台要求,不需要做任何处理,直接DataList To Json 返回前台. 代码: , out recordCount); return Json(allEntities, ...
- 使用ExpandoObject来实现多个Model传送至视图
昨天Insus.NET有实现<使用ViewModel来实现多个Model传送至视图>http://www.cnblogs.com/insus/p/5594134.html 那今天Insus ...
- 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用
在花了不少时间研究学习了MongoDB数据库的相关知识,以及利用C#对MongoDB数据库的封装.测试应用后,决定花一些时间来总结一下最近的研究心得,把这个数据库的应用单独作为一个系列来介绍,希望从各 ...
- 紫橙绿蓝的jQuery幻灯片切换
效果展示 http://hovertree.com/texiao/jquery/77/ 看惯了左右切换的幻灯片,何问起向您推荐一个新颖的,旋转切换,通过点击按钮的相应区域可以使幻灯片以旋转的方式来 ...
- C#的变迁史 - C# 2.0篇
在此重申一下,本文仅代表个人观点,如有不妥之处,还请自己辨别. 第一代的值类型装箱与拆箱的效率极其低下,特别是在集合中的表现,所以第二代C#重点解决了装箱的问题,加入了泛型.1. 泛型 - 珍惜生命, ...
- 【转】php中XML、XSLT的结合运用
原文:http://blog.csdn.net/bjbs_270/article/details/140253 下面我要讲的是一个简单的从数据库中抽取数据,生成XML文档,使用XSLT转换成HTM ...
- Redis数据库安装简介
方法一:Redis手动cmd启动服务 端客户端的方法-------Redis 服务端测试使用1. 下载Redis(https://github.com/mythz/redis-windows)2. 解 ...
- HTML5的Server-Sent Events介绍
body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; } HTML5有一个Server-Sent Events(S ...
- GJM : 使用浏览器的计算力,对抗密码破解 [转载]
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...