CYLTabBarController单行代码 Lottie 动画 TabBar
CYLTabBarController 使用一行代码实现 Lottie 动画 TabBar,支持中间带 + 号的 TabBar 样式,自带红点角标,支持动态刷新。
集成后的效果
既支持默认样式 | 同时也支持创建自定义的形状不规则加号按钮 |
---|---|
支持横竖屏
与其他自定义TabBarController的区别
一行代码支持Lottie动画TabBar样式 |
|
低耦合,易删除 | 1、TabBar设置与业务完全分离,最低只需传两个数组即可完成主流App框架搭建。 2、 PlusButton 的所有设置都在单独的一个类( |
的 |
因为使用原生的控件,并非
|
自动监测是否需要添加“加号”按钮,并能自动设置位置 | CYLTabBarController 既支持类似微信的“中规中矩”的 想支持这种样式,只需自定义一个加号按钮,CYLTabBarController 能检测到它的存在并自动将 “加号”按钮的样式、frame 均在自定义的类中独立实现,不会涉及 tabbar 相关设置。 |
支持动态更新 | 可动态删除PlusButton ,可以动态更新样式
|
即使加号按钮超出了tabbar的区域,超出部分依然能响应点击事件 | 红线内的区域均能响应tabbar相关的点击事件,
|
允许指定加号按钮位置 | Airbnb-app效果: |
支持让 |
效果可见 Airbnb-app 效果,或者下图
|
支持角标自定义View | |
支持多 TabBar 嵌套,并指定 PlusButton 位置 |
|
支持 CocoaPods | 容易集成 |
支持 Swift 项目导入 | 兼容 |
支持横竖屏 |
项目结构
├── CYLTabBarController #核心库文件夹,如果不使用 CocoaPods 集成,请直接将这个文件夹拖拽带你的项目中 └── Example └── Classes ├── Module #模块类文件夹 │ ├── Home │ ├── Message │ ├── Mine │ └── SameCity └── View #这里放着 CYLPlusButton 的子类 CYLPlusButtonSubclass,演示了如何创建自定义的形状不规则加号按钮
使用 CYLTabBarController
四步完成主流App框架搭建:
- 第一步:使用CocoaPods导入CYLTabBarController
- 第二步:设置CYLTabBarController的两个数组:控制器数组和TabBar属性数组
- 第三步:将CYLTabBarController设置为window的RootViewController
- 第四步(可选):创建自定义的形状不规则加号按钮
第一步:使用 CocoaPods 导入 CYLTabBarController
- 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
- 查询 CocoaPods 源中的本库
在终端中运行以下命令:
pod search CYLTabBarController
这里注意,这个命令搜索的是本机上的最新版本,并没有联网查询。如果运行以上命令,没有搜到或者搜不到最新版本,您可以运行以下命令,更新一下您本地的 CocoaPods 源列表。
pod repo update
- 使用 CocoaPods 导入
打开终端,进入到您的工程目录,执行以下命令,会自动生成一个 Podfile 文件。
pod init
然后使用 CocoaPods 进行安装。如果尚未安装 CocoaPods,运行以下命令进行安装:
gem install cocoapods
打开 Podfile,在您项目的 target 下加入以下内容。(此处示例可能是旧版本,使用时请替换为最新版,最新版信息可以从这里获取:)
在文件 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。
建议选择后者:锁定版本,便于团队开发。如:
(此处示例可能是旧版本,使用时请替换为最新版,最新版信息可以从这里获取:)
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 文档。
第二步:设置 CYLTabBarController 的两个数组:控制器数组和 TabBar 属性数组
//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
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { /* *省略部分: * */ [self.window setRootViewController:self.tabBarController]; /* *省略部分: * */ return YES; }
或者将 CYLTabBarController 的子类设为 RootViewCOntroller ,也可以将CYLTabBarController子类的 NavigationViewController 作为 RootViewCOntroller,方便动态更新,Demo 中就是采用后者。
第四步(可选):创建自定义的形状不规则加号按钮
创建一个继承于 CYLPlusButton 的类,要求和步骤:
-
实现
CYLPlusButtonSubclassing
协议 -
子类将自身类型进行注册:调用
[YourClass registerPlusButton]
,需要在 RootViewCOntroller 的 ViewDidLoad 中注册,也可以在-application:didFinishLaunchingWithOptions:
方法里面操作。
这里注意,不建议在子类的 +load
方法中调用,比如像下面这样做,在 iOS10 系统上有 Crash 的风险:
+ (void)load { [super registerPlusButton]; }
协议提供了可选方法:
+ (NSUInteger)indexOfPlusButtonInTabBar; + (CGFloat)multiplierOfTabBarHeight:(CGFloat)tabBarHeight; + (UIViewController *)plusChildViewController; + (BOOL)shouldSelectPlusChildViewController;
作用分别是:
+ (NSUInteger)indexOfPlusButtonInTabBar;
用来自定义加号按钮的位置,如果不实现默认居中,但是如果 tabbar
的个数是奇数则必须实现该方法,否则 CYLTabBarController
会抛出 exception
来进行提示。
主要适用于如下情景:
Airbnb-app效果:
+ (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则表示偏下。
+ (CGFloat)constantOfPlusButtonCenterYOffsetForTabBarHeight:(CGFloat)tabBarHeight;
参考 +multiplierOfTabBarHeight:
中的公式:
PlusButtonCenterY = multiplierOfTabBarHeight * taBarHeight + constantOfPlusButtonCenterYOffset;
也就是说: constantOfPlusButtonCenterYOffset 大于0会向下偏移,小于0会向上偏移。
注意:实现了该方法,但没有实现 +multiplierOfTabBarHeight:
方法,在这种情况下,会在预设逻辑的基础上进行偏移。
详见Demo中的 CYLPlusButtonSubclass
类的实现。
+ (UIViewController *)plusChildViewController;
详见: 点击 PlusButton 跳转到指定 UIViewController
另外,如果加号按钮超出了边界,一般需要手动调用如下代码取消 tabbar 顶部默认的阴影,可在 AppDelegate 类中调用:
//去除 TabBar 自带的顶部阴影 [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];
// iOS10 后 需要使用 -[CYLTabBarController hideTabBarShadowImageView]
见 AppDelegate 类中的演示;
如何调整、自定义 PlusButton
与其它 TabBarItem
的宽度?
CYLTabBarController
规定:
TabBarItem 宽度 = ( TabBar 总宽度 - PlusButton 宽度 ) / (TabBarItem 个数)
所以想自定义宽度,只需要修改 PlusButton
的宽度即可。
比如你就可以在 Demo中的 CYLPlusButtonSubclass.m
类里:
把
[button sizeToFit];
改为
button.frame = CGRectMake(0.0, 0.0, 250, 100); button.backgroundColor = [UIColor redColor];
效果如下, 1.24.0
同时你也可以顺便测试下 CYLTabBarController
的这一个特性:
即使加号按钮超出了tabbar的区域,超出部分依然能响应点击事件
并且你可以在项目中的任意位置读取到 PlusButton
的宽度,借助 CYLTabBarController.h
定义的 CYLPlusButtonWidth
这个extern。可参考 +[CYLTabBarControllerConfig customizeTabBarAppearance:]
里的用法。