欢迎訪问我的个人博客http://mmoaay.photo/

本文主要针对底部凸起的 TabBar 这样的特殊需求,不感兴趣的能够直接绕过~

近期做的一个项目须要底部凸起的 TabBar,效果例如以下:



考虑到 iOS 原生 UITableBar 的定制比較麻烦。所以决定先找一下第三方的解决方式,经过调研发现 RDVTabBarController 比較符合需求。

并且经过实践发现它有例如以下几个优势:

  1. 实现方式与 iOS 原生 UITableBarController 基本一致。方便上手。

  2. RDVTabBar 能够比較简单滴实现底部某个 tab 凸起的效果。
  3. 支持自己定义 badge。

切图

由于 RDVTabBarItem 本身提供例如以下支持:

  • 设置选中和未选中的背景
  • 设置选中和未选中的 Image
  • 设置选中和未选中的文本属性

并且考虑到屏幕的自适应。所以我们在切图的时候把 tab 的 icon 和背景(背景假设是纯色能够不切图)单独切图。

撸代码

首先,我们新建一个继承 RDVTabBarController 的类,然后通过代码或者SB的方式将其设置为根视图。

巨坑

这里有我之前踩过的一个坑,由于一般 App 都会有 UINavigationController 用来做视图导航,所以当 App 底部有 TabBar 的时候,我们有两种选择:

  • 用一个 UITabBarController 包括多个 UINavigationController
  • 用一个 UINavigationController 包括一个 UITabBarController

以前我非常天真(sha bi)的选了第一种。理由是从逻辑上理解更自然,可是结果是被坑慘了。由于业务需求往往是底部 UITabBar 仅仅在几个 Tab 的首页显示,进入下一个页面之后就要隐藏起来。假设採用了第一种方案,你就须要使用 self.hidesBottomBarWhenPushed = YES 或者自己定义动画的方式来隐藏底部 UITabBar。然后坑就出现了——当你须要从某个 Tab 的首页渐变到下一个页面的时候。

假设使用 self.hidesBottomBarWhenPushed = YESUITabBar 仍然会依照原来动画方式隐藏和出现,也就是你会看到 Push 的时候它从右往左消失,Pop 的时候从左往右出现,OMG!

!!

这 tmd 能看么?你的切换动画是渐变的,可是居然有个 UITabBar 在以下跑来跑去,不能忍好么?

这个时候是不是想自己定义动画了?呵呵~不敢告诉你我试了好久,也没有得到一种能够让 UITabBar 渐变消失出现,然后 Tab 里面的页面还能平滑滴配合 UITabBar 做变化的动画效果。

所以!

为什么不选另外一种。在也不须要 self.hidesBottomBarWhenPushed = YES。再也不须要为隐藏和显示 UITabBar 头疼!再也不须要搞各种动画来处理这个巨坑,你所须要做的仅仅是:在 Tab 页面切换的时候把导航栏的标题换一下而已。So easy!

言归正传

好了,骂完以前天真(sha bi)的日子,感觉爽多了~如今继续定制 TabBar。

首先。和 UITableBarController 一样。先设置 TabBarController 管理的 viewControllers

    UIStoryboard *homeStoryboard = [UIStoryboard storyboardWithName:WDHOMESTORYBOARD bundle:nil];
UIViewController *firstViewController=[homeStoryboard instantiateViewControllerWithIdentifier:WDHOMEVIEWCONTROLLER]; UIStoryboard *clothStoryboard = [UIStoryboard storyboardWithName:WDCLOTHSTORYBOARD bundle:nil];
UIViewController *secondViewController=[clothStoryboard instantiateViewControllerWithIdentifier:WDCLOTHVIEWCONTROLLER]; UIStoryboard *userStoryboard = [UIStoryboard storyboardWithName:WDUSERSTORYBOARD bundle:nil];
UIViewController *thirdViewController=[userStoryboard instantiateViewControllerWithIdentifier:WDLOGINVIEWCONTROLLER]; [self setViewControllers:@[firstViewController, secondViewController,
thirdViewController]];

代码非常easy。就是从 SB 中载入 3 个 ViewController 然后放到 viewControllers 里面去。

然后是关键部分,对 TabBar 做定制:

    self.tabBar.frame = CGRectMake(0, 0, SCREEN_SIZE.width, 68);
self.tabBar.backgroundColor = [UIColor clearColor]; // tab 图片
NSArray *tabBarItemImages = @[@"home_icon", @"cloth_icon", @"cloud_icon"];
// tab 标题
NSArray *tabBarItemTitles = @[@"首页", @"", @"云同步"];
NSInteger index = 0;
for (RDVTabBarItem *item in [[self tabBar] items])
{
if (index == 1) {
[item setBackgroundSelectedImage:[UIImage imageNamed:@"tabbar_bg_image"] withUnselectedImage:[UIImage imageNamed:@"tabbar_bg_image"]];
} else {
[item setBackgroundSelectedImage:[WDImageUtil createImageWithColor:TINT_COLOR] withUnselectedImage:[WDImageUtil createImageWithColor:DARK_COLOR]];
item.itemHeight = 57.0f;
} UIImage *selectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_selected",[tabBarItemImages objectAtIndex:index]]];
UIImage *unselectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@",[tabBarItemImages objectAtIndex:index]]]; [item setFinishedSelectedImage:selectedimage withFinishedUnselectedImage:unselectedimage]; [item setTitle:[tabBarItemTitles objectAtIndex:index]];
item.selectedTitleAttributes = @{
NSFontAttributeName: [UIFont boldSystemFontOfSize:12],
NSForegroundColorAttributeName:[UIColor whiteColor],
};
item.unselectedTitleAttributes = @{
NSFontAttributeName: [UIFont boldSystemFontOfSize:12],
NSForegroundColorAttributeName:[UIColor whiteColor],
};
index++;
}

这里我做了几件事情:

  1. 设置 tabBarframe,设置其高度为凸出 Tab button的高度。假设不设置的话,凸出 Tab button会被裁剪掉,例如以下图:

  2. 设置 tabBarbackgroundColor 为透明色。

  3. 然后遍历 tabBaritems,对每一个 item 进行设置。

    这里比較关键的点在于推断是正中间的 item 时,我们须要设置它的背景图片为事先切好的比較特殊的图片,这张图片的分辨率为 1*68(68即为 tabBar 的高度),然后它的上面一部分是透明的。以下一部分填充颜色。以下一部分的高度为 57。这个高度和另外 itemitemHeight 是一致的。这个 itemHeight 的作用有两个:

    • 设置正常 item 的高度。这个高度一般比凸出 Tab button的高度要小(和之前特殊图片配合,这个原理理解下应该就会懂)。
    • 使 Tab 选项中的页面显示正常。假设不设置这个值,Tab 选项中的页面仅仅会填充到凸出 Tab button顶部的位置,这样就会存在中间留白的情况。

      例如以下图:

这样设置好之后就能够达到文章開始时的效果了。

唯一不足就是中间凸起button的背景图片用了一个比較猥琐的办法。假设大家有更科学的办法能够通过以下的评论告诉我~

使用 RDVTabBarController 制作底部凸起的 TabBar 笔记的更多相关文章

  1. AndroidStudio制作底部导航栏以及用Fragment实现切换功能

    前言 大家好,给大家带来AndroidStudio制作底部导航栏以及用Fragment实现切换功能的概述,希望你们喜欢 学习目标 AndroidStudio制作底部导航栏以及用Fragment实现切换 ...

  2. Flutter实战视频-移动电商-49.详细页_Stack制作底部工具栏

    49.详细页_Stack制作底部工具栏 一直悬浮在最下面的 Stack层叠组件.里面用Row 可以横向布局 开始 stack如果想定位就要用position去定位. 修改return返回值的这个地方 ...

  3. Flutter沉浸式状态栏/AppBar导航栏/仿咸鱼底部凸起导航

    Flutter中如何实现沉浸式透明Statusbar状态栏效果? 如下图:状态栏是指android手机顶部显示手机状态信息的位置.android 自4.4开始新加入透明状态栏功能,状态栏可以自定义颜色 ...

  4. [P1169] 棋盘制作 &悬线法学习笔记

    学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...

  5. RDVTabBarController的基本使用 以及tabbar的防止双点击方法

    RDVTabBarController这个库写得相当不错,所以今天就简单介绍下它的基本使用,看里面可以清楚的知道代码规范的重要性,这个库的使用方法和官方的相识 下载地址:https://github. ...

  6. IOS实现中间凸起圆形TabBar

    中间凸起的圆形TabBar曾经比较流行,类似于闲鱼之类的APP就使用了中间凸起TabBar,这两天自己动手实现了一个,效果图如下: 大致原理:重写UITabBar和UITabBarController ...

  7. 01 uni-app框架学习:项目创建及底部导航栏tabBar配置

    1.创建一个项目类型选择uniapp 2. pages里新建3个页面如下 3.在pages.json中配置底部导航tabBar 效果展示:

  8. 小程序 - 底部导航栏“tabBar”

    小程序底部导航 1.app.json页面配置: { "pages": [ "pages/movie/movie", "pages/cinema/cin ...

  9. 添加底部导航栏tabbar

    效果图: 如果要添加底部导航栏,最少2个,最多5个. app.json { "pages": [ "pages/index/index", "page ...

随机推荐

  1. 「2017 山东一轮集训 Day4」基因

    设置 \(\sqrt{n}\) 个关键点,维护出关键点到每个右端点之间的答案以及Pam的左指针,每次暴力向左插入元素即可,为了去重,还需要记录一下Pam上每个节点在每个关键点为左端点插入到时候到最左边 ...

  2. hdu 3949 XOR 线性基 第k小异或和

    题目链接 题意 给定\(n\)个数,对其每一个子集计算异或和,求第\(k\)小的异或和. 思路 先求得线性基. 同上题,转化为求其线性基的子集的第k小异或和. 结论 记\(n\)个数的线性基为向量组\ ...

  3. POJ 2406 Power Strings 简单KMP模板 strcmp

    http://poj.org/problem?id=2406 只是模板,但是有趣的是一个strcmp的字符串比较函数,学习到了... https://baike.baidu.com/item/strc ...

  4. OpenSSL Heartbleed “心脏滴血”漏洞简单攻击示例

    OpenSSL Heartbleed漏洞的公开和流行让许多人兴奋了一把,也让另一些人惊慌了一把. 单纯从攻击的角度讲,我已知道的,网上公开的扫描工具有: 1.  Nmap脚本ssl-heartblee ...

  5. hdu 4112 Break the Chocolate 贪心

    Break the Chocolate Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem. ...

  6. python 用gensim进行文本相似度分析

    http://blog.csdn.net/chencheng126/article/details/50070021 参考于这个博主的博文. 原理 1.文本相似度计算的需求始于搜索引擎. 搜索引擎需要 ...

  7. PID控制原理和算法

    闭环控制是根据控制对象输出反馈来进行校正的控制方式,它是在测量出实际与计划发生偏差时,按定额或标准来进行纠正的.比如控制一个电机的转速,就得有一个测量转速的传感器,并将结果反馈到控制路线上.提到闭环控 ...

  8. ClientDataSet的版本兼容性

    ClientDataSet的版本兼容性 在Delphi的早期版本中,Data这个Variant类型的值内部使用的是AnsiString来存贮的字节流,但我并不确定Delphi从什么时候开始,将其改为了 ...

  9. Entity Framework7 入门之全功能.NET(Console, WinForms, WPF等)使用EF7

    昨天,我们介绍了EF的新特性和开发计划,如果你还不了解,请移步 Entity Framework7 有哪些不同?现在开发到什么程度了? .今天,我们开学习全功能.NET(Full .NET)下使用EF ...

  10. 《Linux兵书》

    <Linux兵书> 基本信息 作者: 刘丽霞    杨宇 丛书名: 程序员藏经阁 出版社:电子工业出版社 ISBN:9787121219924 上架时间:2014-1-13 出版日期:20 ...