Profile
Back to NewsBack
GitHub Trending 10 min
Reader Mode
ChenYilong/CYLTabBarController: [EN]It is an iOS UI module library for adding animation to iOS tabbar items and icons with Lottie, Liquid Glass and adding a bigger center UITabBar Item.  [CN]【中国特色 TabBar】一行代码实现 Lottie 动画TabBar,支持中间

ChenYilong/CYLTabBarController: [EN]It is an iOS UI module library for adding animation to iOS tabbar items and icons with Lottie, Liquid Glass and adding a bigger center UITabBar Item. [CN]【中国特色 TabBar】一行代码实现 Lottie 动画TabBar,支持中间

15 hours ago

[CN]CYLTabBarController【一行代码实现 Lottie 动画 TabBar】iOS27+ Tested

[EN]CYLTabBarController [An animated tabBar supported by Lottie with one line of code]

--------------------------------------------

[CN]阅读须知

[EN]Before Reading

- [CN] mark means Chinese language by default. - [EN] mark means English language. - [CN] 点此获取 QQ 群,Telegram 群交流信息 。 - [EN]Telegram Group to communicate the features or bugs: https://t.me/CYLTabBarController

Preview of latest version

Preview of the latest version on iOS 27+

CYLTabBarController 现已适配iOS27, 新增如下功能: Image

现在适配iPhone duo,横向布局与竖向布局,请更新 CYLTabBarController 1.99.66查看

CYLTabBarController现已适配iOS 27 和 iPhone Duo,更新内容如下:

✅支持横向布局与竖向布局

✅支持扁平样式与液态玻璃样式

✅所有样式均支持加号➕按钮居中显示。

✅零代码适配:已经接入CYLTabBar液态玻璃样式或扁平样式的代码,无需修改代码,更新版本即可适配iPhone duo。

✅审核友好,适配代码均为纯原生公有api,无审核风险。

请更新 CYLTabBarController 1.99.66查看 https://github.com/ChenYilong/CYLTabBarController 演示如下:

Image Image
  • ✅支持iOS27下,0代码,实现扁平风格样式。 无需新增代码, 即可继续使用UI兼容模式,如果你在iOS27下 保留 UIDesignRequiresCompatibility 字段, CYLTabBarController 将会检测该字段, 如果为True,将切换至UI扁平设计样式。iOS27之前, UIDesignRequiresCompatibi字段, 维持系统逻辑。以此实现0代码,切换到扁平风格样式。
  • ✅UI扁平风格作为独立组件集成, 插件化集成, 若仅需液态玻璃效果, 则可实现更低耦合,更小包体积。
  • ✅1比1实现系统扁平风格样式,API接口完全与液态玻璃样式共享, 仅需修改样式属性,即可实现样式切换。
  • ✅支持液态玻璃样式与扁平设计样式,运行期间切换, 支持AB test, 仅需一行代码,修改 样式属性, 即可实现。支持, 默认扁平样式, 灰度下发,逐渐切换至液态玻璃。
  • ✅液态玻璃 继承自UITabBar , 在支持所有系统样式设置。在此基础上, 实现加号按钮, 灵活性优于系统 TabBar。
  • ✅支持Lottie 动画, iOS26和iOS27液态玻璃, 红点角标动画, 同时展示。
  • ✅即刻升级至 1.99.41 尝试, iOS27正式版本发布前, 我将至少发布3个版本,用来支持iOS27正式版适配, 如遇到问题请前往 GitHub 提issue, 请勿社交媒体留言。issue为唯一问题反馈途径。
CYLTabBarController 现已支持 iOS26 上实现以下效果, 请更新至版本1.99.39以上版本:
  • ✅同时展示 Lottie动画与液态玻璃效果;
  • ✅支持将加号➕按钮,展示在液态玻璃效果上,并居中展示。保留 CYLTabBarController 旧版本的所有加号按钮逻辑。仅增加玻璃遮罩效果;
  • ✅未使用私有API实现液态玻璃,可通过代码静态扫描,Apple 审核过审安全;
  • ✅采用纯原生的液态玻璃效果,支持 iOS 系统设置对液态玻璃属性的全部修改操作;
  • ✅企业生产环境级别开源解决方案;
  • ✅对于已经集成 CYLTabBarController 的开发者友好,升级适配开发难度, 代码修改低于10行,升级总时长低于1小时;
  • ✅不依赖UI兼容模式, iOS27 过审友好;
  • ✅不依赖UI兼容模式, 实现扁平风格UI, iOS27 过审友好;
  • ✅ GitHub.com/ChenYilong/CYLTabBarController
Image Image

!Image

!Image !Image !Image !Image !Image 1.99.39 版本, 现已支持 iOS26上 , APP 运行中, 增加或者删除加号按钮, 效果见下面的演示,即刻访问:https://github.com/ChenYilong/CYLTabBarController Demo 进行尝试:

Image Image

[CN]谁在用?上架APP列表[EN]who are using? List of App published

APP name link icon | image |APP name link icon | image :-------------:|:-------------:|:-------------:|:-------------: 海底捞 App Store Link !enter image description here | !enter image description here | C家 App Store Link !enter image description here | Lottie 效果 | 淘必中-淘宝推出的一款具有营销购物功能的APP App Store Link !enter image description here | !enter image description here | 慧诊健康 App Store Link !enter image description here|!enter image description here 究竟大学 App Store Link !enter image description here | !enter image description here | 蕉片 - 短视频拍摄剪辑出电影大片 App Store Link !enter image description here| 闪剧 - 可以玩的短视频 App Store Link !enter image description here| !enter image description here | 土狗云商城 App Store Link !enter image description here| Analyst.ai App Store Link !enter image description here| !enter image description here | 美膳校园 App Store Link !enter image description here| !enter image description here 全聚星 App Store Link !enter image description here |!enter image description here | Yesoul App Store Link !enter image description here | !enter image description here 贵州充电通 App Store Link !enter image description here | !enter image description here | 卓尔购 App Store Link !enter image description here | !enter image description here 卓越管家 App Store Link !enter image description here | !enter image description here | 悦守护 App Store Link | 筑集采采购端 App Store Link !enter image description here | | 筑集采供应端 App Store Link !enter image description here | | 桂富宝 App Store Link !enter image description here | !enter image description here | 小猪奔奔 App Store Link !enter image description here | !enter image description here 娃娃坞(开发中) | | 更多APP请访问 《使用 CYLTabBarController 做的 APP,来这里报道下吧》 | 如果你正在使用也请提交到这里 《使用 CYLTabBarController 做的 APP,来这里报道下吧》

[CN]导航

[EN]CONTENTS

- 第一步:使用CocoaPods导入CYLTabBarController - 第二步:设置CYLTabBarController的两个数组:控制器数组和TabBar属性数组 - 第三步:将CYLTabBarController设置为window的RootViewController - 第四步(可选):创建自定义的形状不规则加号按钮 - 自定义 TabBar 样式 - 捕获 TabBar 点击事件 - 点击 TabBarButton 时添加动画 - 横竖屏适配 - 访问初始化好的 CYLTabBarController 对象 - 点击 PlusButton 跳转到指定 UIViewController - 让TabBarItem仅显示图标,并使图标垂直居中 - 多TabBar嵌套,并指定PlusButton位置 - 在 Swift 项目中使用 CYLTabBarController - 搭配 Storyboard 使用 CYLTabBarController - 源码实现原理

与其他自定义TabBarController的区别

Comparetion with other Libraries

[CN]特点

[EN]Features |[CN]解释

[EN]Explanation :-------------:|:-------------: [CN]一行代码支持Lottie动画TabBar样式

[EN] It only needs one line of code to have an animated TabBar with Lottie. |[CN]使用方法

[EN]How to add animation of Lottie with one line of code.

!https://github.com/ChenYilong

!https://github.com/ChenYilong [CN]低耦合,易删除

[EN]Loose coupling | [CN]1、TabBar设置与业务完全分离,最低只需传两个数组即可完成主流App框架搭建。

[EN]1. This library is independent of your business codes which only needs two array parameters to be passed.

[CN]2、 PlusButton 的所有设置都在单独的一个类( CYLPlusButton 的子类)中实现:删除该特定的类,就能完全将 PlusButton 从项目中删除掉。

[EN]2.PlusButton is also independent. If you delete the code of this class, you remove the PlusButton feature from your UI on screen completely. [CN]TabBar 以及 TabBar 内的 TabBarItem 均使用系统原生的控件

[EN]TabBar and TabBarItem those parts of this library both are system objects. | [CN]因为使用原生的控件,并非 UIButton 或 UIView 。好处如下:

[EN]Advantages of quitting choosing UIButton or UIView:

1. 无需反复调“间距位置等”来接近系统效果。

[EN]There is not need to adjust those object to make them close to a system object appearance.

2. 在push到下一页时 TabBar 的隐藏和显示之间的过渡效果跟系统一致(详见“ 集成后的效果 ”部分,给出了效果图)

[EN]2. A push animation is same to a system objects appearance.

3. 原生控件,所以可以使用诸多系统API,比如:可以使用 [UITabBar appearance]; 、 [UITabBarItem appearance]; 设置样式。(详见“补充说明 ”部分,给出了响应代码示例)

[EN]3.It is convenient to use the system API such as [UITabBar appearance];, [UITabBarItem appearance];, etc. 自动监测是否需要添加“加号”按钮,

并能自动设置位置

[EN] It is able to check if need to add a PlusButton automatically. |CYLTabBarController 既支持类似微信的“中规中矩”的 TabBarController 样式,并且默认就是微信这种样式,同时又支持类似“微博”或“淘宝闲鱼”这种具有不规则加号按钮的 TabBarController 。想支持这种样式,只需自定义一个加号按钮,CYLTabBarController 能检测到它的存在并自动将 tabBar 排序好,无需多余操作,并且也预留了一定接口来满足自定义需求。

“加号”按钮的样式、frame均在自定义的类中独立实现,不会涉及tabbar相关设置。 支持动态更新 | 可动态删除PlusButton ,可以动态更新样式

!https://github.com/ChenYilong 即使加号按钮超出了tabbar的区域,

超出部分依然能响应点击事件 | 红线内的区域均能响应tabbar相关的点击事件,

!https://github.com/ChenYilong 允许指定加号按钮位置 | 效果如下:

!iTeaTime(技术清谈)

Airbnb-app效果:

!iTeaTime(技术清谈) 支持让 TabBarItem 仅显示图标,并自动使图标垂直居中,支持自定义TabBar高度 | 效果可见Airbnb-app效果,或者下图

!enter image description here 支持角标自定义View | !enter image description here 支持多TabBar嵌套,并指定PlusButton位置 | !enter image description here 支持CocoaPods |容易集成 支持Swift项目导入 | 兼容 支持横竖屏 | --

(学习交流群:515295083)

集成后的效果:

既支持默认样式 | 同时也支持创建自定义的形状不规则加号按钮 -------------|------------ !https://github.com/ChenYilong| !https://github.com/ChenYilong

支持横竖屏

本仓库配套Demo的效果:| 另一个Demo

使用CYLTabBarController实现了微博Tabbar框架,

效果如下 -------------|------------- !https://github.com/ChenYilong | !https://github.com/ChenYilong

项目结构

!https://github.com/ChenYilong

做下说明:

``Objective-C

├── CYLTabBarController #核心库文件夹,如果不使用 CocoaPods 集成,请直接将这个文件夹拖拽带你的项目中 └── Example └── Classes    ├── Module #模块类文件夹 │   ├── Home │   ├── Message │   ├── Mine    │   └── SameCity    └── View #这里放着 CYLPlusButton 的子类 CYLPlusButtonSubclass,演示了如何创建自定义的形状不规则加号按钮

## 使用CYLTabBarController

四步完成主流App框架搭建:

1. 第一步:使用CocoaPods导入CYLTabBarController 2. 第二步:设置CYLTabBarController的两个数组:控制器数组和TabBar属性数组 3. 第三步:将CYLTabBarController设置为window的RootViewController 4. 第四步(可选):创建自定义的形状不规则加号按钮

第一步:使用CocoaPods导入CYLTabBarController

1. CocoaPods 安装

  如果您的机器上已经安装了 CocoaPods,直接进入下一步即可。

  如果您的网络已经翻墙,在终端中运行如下命令直接安装:

 

  sudo gem install cocoapods  
  如果您的网络不能翻墙,可以通过国内 Ruby China 的 RubyGems 镜像进行安装。

  在终端依次运行以下命令:

 

  gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/     sudo gem install cocoapods  
2. 查询 CocoaPods 源中的本库

  在终端中运行以下命令:

 

  pod search CYLTabBarController  
   这里注意,这个命令搜索的是本机上的最新版本,并没有联网查询。如果运行以上命令,没有搜到或者搜不到最新版本,您可以运行以下命令,更新一下您本地的 CocoaPods 源列表。

 

  pod repo update  
3. 使用 CocoaPods 导入

  打开终端,进入到您的工程目录,执行以下命令,会自动生成一个 Podfile 文件。

 

  pod init  
  然后使用 CocoaPods 进行安装。如果尚未安装 CocoaPods,运行以下命令进行安装:
gem install cocoapods
  打开 Podfile,在您项目的 target 下加入以下内容。(此处示例可能是旧版本,使用时请替换为最新版,最新版信息可以从这里获取:<a href="https://github.com/ChenYilong/CYLTabBarController/blob/master/CYLTabBarController.podspec"><img src="https://img.shields.io/badge/Pod-GetLatestVersion-green.svg?style=flat"></a>)

  在文件 Podfile 中加入以下内容:

pod 'CYLTabBarController', '~> 1.24.0'
  然后在终端中运行以下命令:
pod install
  或者这个命令:
# 禁止升级 CocoaPods 的 spec 仓库,否则会卡在 Analyzing dependencies,非常慢 pod update --verbose --no-repo-update
  如果提示找不到库,则可去掉 --no-repo-update。

  完成后1.24.0,CocoaPods 会在您的工程根目录下生成一个 .xcworkspace 文件。您需要通过此文件打开您的工程,而不是之前的 .xcodeproj。

CocoaPods 使用说明

指定 CYLTabBarController 版本

CocoaPods 中,有几种设置 CYLTabBarController 版本的方法。如:

>= 1.n.X 会根据您本地的 CocoaPods 源列表,导入不低于 1.(n+1).X 版本的 CYLTabBarController。

~> 1.n.X 会根据您本地的 CocoaPods 源列表,介于 1.n.X~1.(n+1).0 之前版本的 CYLTabBarController。

建议选择后者:锁定版本,便于团队开发。如:

(此处示例可能是旧版本,使用时请替换为最新版,最新版信息可以从这里获取:<a href="https://github.com/ChenYilong/CYLTabBarController/blob/master/CYLTabBarController.podspec"><img src="https://img.shields.io/badge/Pod-GetLatestVersion-green.svg?style=flat"></a>)

pod 'CYLTabBarController', '~> 1.24.0'
- 升级本地 CocoaPods 源

  CocoaPods 有一个中心化的源,默认本地会缓存 CocoaPods 源服务器上的所有 CYLTabBarController 版本。

如果搜索的时候没有搜到或者搜不到最新版本,可以执行以下命令更新一下本地的缓存。

pod repo update
- 升级工程的 CYLTabBarController 版本

更新您工程目录中 Podfile 指定的 CYLTabBarController 版本后,在终端中执行以下命令。

pod update
- 清除 Cocoapods 本地缓存

特殊情况下,由于网络或者别的原因,通过 CocoaPods 下载的文件可能会有问题。

这时候您可以删除 CocoaPods 的缓存(~/Library/Caches/CocoaPods/Pods/Release 目录),再次导入即可。

- 查看当前使用的 CYLTabBarController 版本

您可以在 Podfile.lock 文件中看到您工程中使用的 CYLTabBarController 版本。

关于 CocoaPods 的更多内容,您可以参考 CocoaPods 文档。

使用 Carthage 导入 CYLTabBarController(可选)

除了 CocoaPods 和 Swift Package Manager,也可以通过 Carthage 集成本库。在 Cartfile 中添加:

github "ChenYilong/CYLTabBarController"
然后执行:
carthage update --use-xcframeworks
构建完成后,将生成的 CYLTabBarController.xcframework 拖入工程,并在 "Frameworks, Libraries, and Embedded Content" 中设置为 Embed & Sign。

> 说明:Carthage 构建的是不含 Lottie 动画相关文件(LottieSwift 目录)的核心功能集,与 CocoaPods 的 Core子规范(subspec)范围一致。

第二步:设置CYLTabBarController的两个数组:控制器数组和TabBar属性数组

Objective-C //MainTabBarController @interface MainTabBarController : CYLTabBarController @end
  • (instancetype)init {
if (!(self = [super init])) { return nil; } /** * 以下两行代码目的在于手动设置让TabBarItem只显示图标,不显示文字,并让图标垂直居中。 * 等效于在 -tabBarItemsAttributesForController 方法中不传 CYLTabBarItemTitle 字段。 * 更推荐后一种做法。 */ UIEdgeInsets imageInsets = UIEdgeInsetsZero;//UIEdgeInsetsMake(4.5, 0, -4.5, 0); UIOffset titlePositionAdjustment = UIOffsetMake(0, -3.5); CYLTabBarController *tabBarController = [CYLTabBarController tabBarControllerWithViewControllers:self.viewControllers tabBarItemsAttributes:self.tabBarItemsAttributesForController imageInsets:imageInsets titlePositionAdjustment:titlePositionAdjustment context:nil ]; [self customizeTabBarAppearance:tabBarController]; self.navigationController.navigationBar.hidden = YES; return (self = (MainTabBarController *)tabBarController); }
  • (NSArray *)viewControllers {
CYLHomeViewController *firstViewController = [[CYLHomeViewController alloc] init]; UIViewController *firstNavigationController = [[CYLBaseNavigationController alloc] initWithRootViewController:firstViewController]; [firstViewController cyl_setHideNavigationBarSeparator:YES]; CYLSameCityViewController *secondViewController = [[CYLSameCityViewController alloc] init]; UIViewController *secondNavigationController = [[CYLBaseNavigationController alloc] initWithRootViewController:secondViewController]; [secondViewController cyl_setHideNavigationBarSeparator:YES]; NSArray *viewControllers = @[ firstNavigationController, secondNavigationController, ]; return viewControllers; }
  • (NSArray *)tabBarItemsAttributesForController {
NSDictionary *firstTabBarItemsAttributes = @{ CYLTabBarItemTitle : @"首页", CYLTabBarItemImage : self.darkMode ? @"home_highlight" : @"home_normal", / NSString and UIImage are supported/ CYLTabBarItemSelectedImage : @"home_highlight", / NSString and UIImage are supported/ }; NSDictionary *secondTabBarItemsAttributes = @{ CYLTabBarItemTitle : @"同城", CYLTabBarItemImage : self.darkMode ? @"fishpond_highlight" : @"fishpond_normal", CYLTabBarItemSelectedImage : @"fishpond_highlight", };

NSArray *tabBarItemsAttributes = @[ firstTabBarItemsAttributes, secondTabBarItemsAttributes, ]; return tabBarItemsAttributes; }

在这个字典中,CYLTabBarItemImage 和 CYLTabBarItemSelectedImage 支持 NSString、UIImage
两种格式。CYLTabBarItemTitle 不设置将只展示图标,并会对布局作出居中处理。

第三步:将CYLTabBarController设置为window的RootViewController

Objective-C - (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { / 省略部分: / [self.window setRootViewController:self.tabBarController]; / 省略部分: / return YES; }
或者将 CYLTabBarController 的子类设为 RootViewCOntroller ,也可以将CYLTabBarController子类的 NavigationViewController 作为 RootViewCOntroller,方便动态更新,Demo 中就是采用后者。

第四步(可选):创建自定义的形状不规则加号按钮

创建一个继承于 CYLPlusButton 的类,要求和步骤:

1. 实现 CYLPlusButtonSubclassing 协议

2. 子类将自身类型进行注册:调用 [YourClass registerPlusButton],需要在 RootViewCOntroller 的 ViewDidLoad 中注册,也可以在 -application:didFinishLaunchingWithOptions: 方法里面操作。

这里注意,不建议在子类的 +load 方法中调用,比如像下面这样做,在 iOS10 系统上有 Crash 的风险:

Objective-C + (void)load { [super registerPlusButton]; }
协议提供了可选方法:
Objective-C + (NSUInteger)indexOfPlusButtonInTabBar; + (CGFloat)multiplierOfTabBarHeight:(CGFloat)tabBarHeight; + (UIViewController *)plusChildViewController; + (BOOL)shouldSelectPlusChildViewController;
作用分别是:
Objective-C + (NSUInteger)indexOfPlusButtonInTabBar;
用来自定义加号按钮的位置,如果不实现默认居中,但是如果 tabbar 的个数是奇数则必须实现该方法,否则 CYLTabBarController 会抛出 exception 来进行提示。

主要适用于如下情景:

<p align="center"><a href="https://mp.weixin.qq.com/s/A4e5h3xgIEh6PInf1Rjqsw"><img src="https://tva1.sinaimg.cn/large/006y8mN6gy1g92nics1hvj30a906u3ym.jpg"></a></p>

Airbnb-app效果:

<p align="center"><a href="https://mp.weixin.qq.com/s/A4e5h3xgIEh6PInf1Rjqsw"><img src="https://tva1.sinaimg.cn/large/006y8mN6gy1g92nir57tmg308w0fsapi.gif"></a></p>

Objective-C + (CGFloat)multiplierOfTabBarHeight:(CGFloat)tabBarHeight;
该方法是为了调整自定义按钮中心点Y轴方向的位置,建议在按钮超出了 tabbar 的边界时实现该方法。返回值是自定义按钮中心点Y轴方向的坐标除以 tabbar 的高度,如果不实现,会自动进行比对,预设一个较为合适的位置,如果实现了该方法,预设的逻辑将失效。

内部实现时,会使用该返回值来设置 PlusButton 的 centerY 坐标,公式如下: PlusButtonCenterY = multiplierOfTabBarHeight * taBarHeight + constantOfPlusButtonCenterYOffset;

也就是说:如果 constantOfPlusButtonCenterYOffset 为0,同时 multiplierOfTabBarHeight 的值是0.5,表示 PlusButton 居中,小于0.5表示 PlusButton 偏上,大于0.5则表示偏下。

Objective-C + (CGFloat)constantOfPlusButtonCenterYOffsetForTabBarHeight:(CGFloat)tabBarHeight;
参考 +multiplierOfTabBarHeight: 中的公式:

PlusButtonCenterY = multiplierOfTabBarHeight * taBarHeight + constantOfPlusButtonCenterYOffset;

也就是说: constantOfPlusButtonCenterYOffset 大于0会向下偏移,小于0会向上偏移。

注意:实现了该方法,但没有实现 +multiplierOfTabBarHeight: 方法,在这种情况下,会在预设逻辑的基础上进行偏移。

详见Demo中的 CYLPlusButtonSubclass 类的实现。

Objective-C + (UIViewController *)plusChildViewController;
详见: 点击 PlusButton 跳转到指定 UIViewController

另外,如果加号按钮超出了边界,一般需要手动调用如下代码取消 tabbar 顶部默认的阴影,可在 AppDelegate 类中调用:

Objective-C //去除 TabBar 自带的顶部阴影 [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];
// iOS10 后 需要使用 -[CYLTabBarController hideTabBarShadowImageView] 见 AppDelegate 类中的演示;

如何调整、自定义 PlusButton 与其它 TabBarItem 的宽度?

CYLTabBarController 规定:

Objective-C TabBarItem 宽度 = ( TabBar 总宽度 - PlusButton 宽度 ) / (TabBarItem 个数)
所以想自定义宽度,只需要修改 PlusButton 的宽度即可。

比如你就可以在 Demo中的 CYLPlusButtonSubclass.m 类里: 把

Objective-C [button sizeToFit];
改为
Objective-C button.frame = CGRectMake(0.0, 0.0, 250, 100); button.backgroundColor = [UIColor redColor];
效果如下,
1.24.0

<p align="center"><a href="https://mp.weixin.qq.com/s/A4e5h3xgIEh6PInf1Rjqsw"><img src="https://tva1.sinaimg.cn/large/006y8mN6ly1g6ur17yxa3j30yi0c6abk.jpg"></a></p>

同时你也可以顺便测试下 CYLTabBarController 的这一个特性:

> 即使加号按钮超出了tabbar的区域,超出部分依然能响应点击事件

并且你可以在项目中的任意位置读取到 PlusButton 的宽度,借助 CYLTabBarController.h 定义的 CYLPlusButtonWidth 这个extern。可参考 +[CYLTabBarControllerConfig customizeTabBarAppearance:] 里的用法。

补充说明

自定义 TabBar 样式

如果想更进一步的自定义 TabBar 样式可在 -application:didFinishLaunchingWithOptions: 方法中设置

Objective-C /** * tabBarItem 的选中和不选中文字属性、背景图片 */
  • (void)customizeInterface {
// 普通状态下的文字属性 NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary]; normalAttrs[NSForegroundColorAttributeName] = [UIColor grayColor]; // 选中状态下的文字属性 NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary]; selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor]; // 设置文字属性 UITabBarItem *tabBar = [UITabBarItem appearance]; [tabBar setTitleTextAttributes:normalAttrs forState:UIControlStateNormal]; [tabBar setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected]; // 设置背景图片 UITabBar *tabBarAppearance = [UITabBar appearance]; [tabBarAppearance setBackgroundImage:[UIImage imageNamed:@"tabbar_background"]]; }

- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { / 省略部分: / [self.window makeKeyAndVisible]; [self customizeInterface]; return YES; }

####  捕获 TabBar 点击事件

实现 CYLTabBarController 的如下几个代理方法即可捕获点击事件。 下面这个方法能捕获当前点击的 TabBar 上的控件,可以是 UITabBarButton、也可以 PlusButton、也可以是添加到 TabBar 上的任意 UIControl 的子类。但是如果 PlusButton 也添加了点击事件,那么点击 PlusButton 将不会被触发这个代理方法。

Objective-C //CYLTabBarController.h

@protocol CYLTabBarControllerDelegate

/*! * @param tabBarController The tab bar controller containing viewController. * @param control Selected UIControl in TabBar. * @attention If PlusButton also add an action, then this delegate method will not be invoked when the PlusButton is selected. */

  • (void)tabBarController:(UITabBarController )tabBarController didSelectControl:(UIControl )control;
@end

下面这个方法能捕获跳转前所在的控制器,以及跳转到的目标控制器。
Objective-C //UITabBarController.h @protocol UITabBarControllerDelegate @optional
  • (BOOL)tabBarController:(UITabBarController )tabBarController shouldSelectViewController:(UIViewController )viewController NS_AVAILABLE_IOS(3_0);
@end
注意:在调用该方法时应该始终调用
    [[self cyl_tabBarController] updateSelectionStatusIfNeededForTabBarController:tabBarController shouldSelectViewController:viewController]; 来确保 PlusButton 的选中状态。示例如下:
Objective-C
  • (BOOL)tabBarController:(UITabBarController )tabBarController shouldSelectViewController:(UIViewController )viewController {
[[self cyl_tabBarController] updateSelectionStatusIfNeededForTabBarController:tabBarController shouldSelectViewController:viewController]; return YES; }
相关用法已经在 Demo 中展示。

遵循协议的方式如下:

Objective-C @interface AppDelegate ()

@end

  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions {
//... tabBarControllerConfig.tabBarController.delegate = self; //... return YES; }
###  点击 TabBarButton 时添加动画

Demo 演示的效果图:

<p align="center"><a href="https://mp.weixin.qq.com/s/A4e5h3xgIEh6PInf1Rjqsw"><img src="https://ww1.sinaimg.cn/large/006tNbRwly1fg9hu6qnwbg308v0gctcc.gif"></a></p>

实现如下代理方法,就能得到对应的选中控件,可以在控件上直接添加动画。

Objective-C //CYLTabBarController.h

@protocol CYLTabBarControllerDelegate

/*! * @param tabBarController The tab bar controller containing viewController. * @param control Selected UIControl in TabBar. */

  • (void)tabBarController:(UITabBarController )tabBarController didSelectControl:(UIControl )control;
@end

Demo 中示例代码如下:

遵循协议

Objective-C @interface AppDelegate ()

@end

Objective-C //AppDelegate.m
  • (void)tabBarController:(UITabBarController )tabBarController didSelectControl:(UIControl )control {
UIView *animationView; // 如果 PlusButton 也添加了点击事件,那么点击 PlusButton 后不会触发该代理方法。 if ([control isKindOfClass:[CYLExternPlusButton class]]) { UIButton *button = CYLExternPlusButton; animationView = button.imageView; } else if ([control isKindOfClass:NSClassFromString(@"UITabBarButton")]) { for (UIView *subView in control.subviews) { if ([subView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) { animationView = subView; } } } if ([self cyl_tabBarController].selectedIndex % 2 == 0) { [self addScaleAnimationOnView:animationView]; } else { [self addRotateAnimationOnView:animationView]; } }

//缩放动画

  • (void)addScaleAnimationOnView:(UIView *)animationView {
//需要实现的帧动画,这里根据需求自定义 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"transform.scale"; animation.values = @[@1.0,@1.3,@0.9,@1.15,@0.95,@1.02,@1.0]; animation.duration = 1; animation.calculationMode = kCAAnimationCubic; [animationView.layer addAnimation:animation forKey:nil]; }

//旋转动画

  • (void)addRotateAnimationOnView:(UIView *)animationView {
[UIView animateWithDuration:0.32 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ animationView.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0); } completion:nil]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [UIView animateWithDuration:0.70 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{ animationView.layer.transform = CATransform3DMakeRotation(2 * M_PI, 0, 1, 0); } completion:nil]; }); }
### 横竖屏适配

TabBar 横竖屏适配时,如果你添加了 PlusButton,且适配时用到了 TabBarItem 的宽度, 不建议使用系统的UIDeviceOrientationDidChangeNotification , 请使用库里的 CYLTabBarItemWidthDidChangeNotification 来更新 TabBar 布局,最典型的场景就是,根据 TabBarItem 在不同横竖屏状态下的宽度变化来切换选中的TabBarItem 的背景图片。Demo 里 CYLTabBarControllerConfig.m 给出了这一场景的用法:

CYLTabBarController.h 中提供了 CYLTabBarItemWidth 这一extern常量,并且会在 TabBarItem 的宽度发生变化时,及时更新该值,所以用法就如下所示:

Objective-C
  • (void)updateTabBarCustomizationWhenTabBarItemWidthDidUpdate {
void (^deviceOrientationDidChangeBlock)(NSNotification ) = ^(NSNotification notification) { [self tabBarItemWidthDidUpdate]; }; [[NSNotificationCenter defaultCenter] addObserverForName:CYLTabBarItemWidthDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:deviceOrientationDidChangeBlock]; }

  • (void)tabBarItemWidthDidUpdate {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; if ((orientation == UIDeviceOrientationLandscapeLeft) || (orientation == UIDeviceOrientationLandscapeRight)) { NSLog(@"Landscape Left or Right !"); } else if (orientation == UIDeviceOrientationPortrait){ NSLog(@"Landscape portrait!"); } CGSize selectionIndicatorImageSize = CGSizeMake(CYLTabBarItemWidth, [self cyl_tabBarController].tabBar.bounds.size.height); [[self cyl_ta

... (README truncated for length)

Chat with me