Skip to content

最低只需传两个数组即可完成主流App框架搭建

License

Notifications You must be signed in to change notification settings

kakukeme/CYLTabBarController

 
 

Repository files navigation

CYLTabBarController【低耦合集成TabBarController】

![enter image description here](https://img.shields.io/badge/pod-v1.0.5-brightgreen.svg) ![enter image description here](https://img.shields.io/badge/Objective--C-compatible-orange.svg) ![enter image description here](https://img.shields.io/badge/platform-iOS%207.0%2B-ff69b4.svg)

导航

  1. 与其他自定义TabBarController的区别
  2. 集成后的效果
  3. 使用CYLTabBarController
  4. 第一步:使用cocoaPods导入CYLTabBarController
  5. 第二步:设置CYLTabBarController的两个数组:控制器数组和TabBar属性数组
  6. 第三步:将CYLTabBarController设置为window的RootViewController
  7. 第四步(可选):创建自定义的形状不规则加号按钮
  8. 补充说明
  9. Q-A

与其他自定义TabBarController的区别

- 特点 解释
1 低耦合 与业务完全分离,最低只需传两个数组即可完成主流App框架搭建
2 TabBar 以及 TabBar 内的 TabBarItem 均使用系统原生的控件 因为使用原生的控件,并非 UIButtonUIView 。好处如下:

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

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

3. 原生控件,所以可以使用诸多系统API,比如:可以使用 [UITabBar appearance]; [UITabBarItem appearance]; 设置样式。(详见“补充说明 ”部分,给出了响应代码示例)
3 自动监测是否需要添加“加号”按钮,

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

“加号”按钮的样式、frame均在自定义的类中独立实现,不会涉及tabbar相关设置。
4 即使加号按钮超出了tabbar的区域,

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

enter image description here
5 支持CocoaPods 容易集成

(学习交流群:465239521)

集成后的效果:

既支持默认样式 同时也支持创建自定义的形状不规则加号按钮
enter image description here enter image description here
本仓库配套Demo的效果: 另一个Demo 使用CYLTabBarController实现了微博Tabbar框架,效果如下
enter image description here enter image description here

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

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

第一步:使用CocoaPods导入CYLTabBarController

Podfile 中进行如下导入:

pod 'CYLTabBarController'

然后使用 cocoaPods 进行安装:

如果尚未安装 Cocoapods, 运行以下命令进行安装:

gem install cocoapods

安装成功后就可以安装依赖了:

建议使用如下方式:

# 禁止升级CocoaPods的spec仓库,否则会卡在 Analyzing dependencies ,非常慢 
pod update --verbose --no-repo-update

如果提示找不到库,则可去掉 --no-repo-update

pod update

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

- (void)setupViewControllers {
   CYLHomeViewController *firstViewController = [[CYLHomeViewController alloc] init];
   UIViewController *firstNavigationController = [[UINavigationController alloc]
                                                  initWithRootViewController:firstViewController];
   
   CYLSameFityViewController *secondViewController = [[CYLSameFityViewController alloc] init];
   UIViewController *secondNavigationController = [[UINavigationController alloc]
                                                   initWithRootViewController:secondViewController];
   

   CYLTabBarController *tabBarController = [[CYLTabBarController alloc] init];
   [self customizeTabBarForController:tabBarController];
   
   [tabBarController setViewControllers:@[
                                          firstNavigationController,
                                          secondNavigationController,
                                          ]];
   self.tabBarController = tabBarController;
}

/*
*
在`-setViewControllers:`之前设置TabBar的属性,
*
*/
- (void)customizeTabBarForController:(CYLTabBarController *)tabBarController {
   
   NSDictionary *dict1 = @{
                           CYLTabBarItemTitle : @"首页",
                           CYLTabBarItemImage : @"home_normal",
                           CYLTabBarItemSelectedImage : @"home_highlight",
                           };
   NSDictionary *dict2 = @{
                           CYLTabBarItemTitle : @"同城",
                           CYLTabBarItemImage : @"mycity_normal",
                           CYLTabBarItemSelectedImage : @"mycity_highlight",
                           };

   NSArray *tabBarItemsAttributes = @[ dict1, dict2 ];
   tabBarController.tabBarItemsAttributes = tabBarItemsAttributes;
}

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

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

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

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

  1. 实现 CYLPlusButtonSubclassing 协议

  2. 子类将自身类型进行注册,一般可在 applicationapplicationDelegate 方法里面调用 [YourClass registerSubClass] 或者在子类的 +load 方法中调用:

+(void)load {
   [super registerSubclass];
}

协议提供了两个可选方法:

+ (NSUInteger)indexOfPlusButtonInTabBar;
+ (CGFloat)multiplerInCenterY;

作用分别是:

+ (NSUInteger)indexOfPlusButtonInTabBar;

用来自定义加号按钮的位置,如果不实现默认居中,但是如果 tabbar 的个数是奇数则必须实现该方法,否则 CYLTabBarController 会抛出 exception 来进行提示。

+ (CGFloat)multiplerInCenterY;

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

详见Demo中的 CYLPlusButtonSubclass 类的实现。

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

   //去除 TabBar 自带的顶部阴影
   [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]];

补充说明

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

/**
*  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;
}

更多文档信息可查看 CocoaDocs:CYLTabBarController

Q-A

Q:为什么放置6个TabBarItem会显示异常?

A:

Apple 规定:

一个 TabBar 上只能出现最多5个 TabBarItem ,第六个及更多的将不被显示。

另外注意,Apple检测的是 UITabBarItem 及其子类,所以放置“加号按钮”,这是 UIButton 不在“5个”里面。

最多只能添加5个 TabBarItem ,也就是说加上“加号按钮”,一共最多在一个 TabBar 上放置6个控件。否则第6个及之后出现 TabBarItem 会被自动屏蔽掉。而且就Apple的审核机制来说,超过5个也会被直接拒绝上架。

Q:我把 demo 两侧的 item 各去掉一个后,按钮的响应区域就变成下图的样子了: wechat_1445851872

A:这个是iOS系统对 tabBar 做的优化,请在真机上进行右手体验。如果你将iPhone切换到左手模式,触摸区域将“反过来”,有兴趣可以试一下。

Q: 如何实现添加选中背景色的功能 ,像下面这样: screen shot 2015-10-28 at 9 21 56 am

A:我已经在 Demo 中添加了如何实现该功能的代码: 详情见 CYLTabBarControllerConfig 类中下面方法的实现:

/**
*  更多TabBar自定义设置:比如:tabBarItem 的选中和不选中文字和背景图片属性、tabbar 背景图片属性
*/
- (void)customizeTabBarAppearance;

效果如下: simulator screen shot 2015 10 28 11 44 32

Q:当ViewController设置的self.title和tabBarItemsAttributes中对应的title不一致的时候,会出现如图的错误,排序不对了

A:在 v1.0.7 版本中已经修复了该 bug,但是也需要注意:

请勿使用 self.title = @"同城"; 这种方式,请使用 self.navigationItem.title = @"同城";

self.title = @"同城"; 这种方式,如果和tabBarItemsAttributes中对应的title不一致的时候可能会导致如下现象(不算 bug,但看起来也很奇怪):

enter image description here

规则如下:

   self.navigationItem.title = @"同城";    //✅sets navigation bar title.The right way to set the title of the navigation
   self.tabBarItem.title = @"同城23333";   //❌sets tab bar title. Even the `tabBarItem.title` changed, this will be ignored in  tabbar.
   self.title = @"同城1";                  //❌sets both of these. Do not do this‼️‼️ This may cause something strange like this : http://i68.tinypic.com/282l3x4.jpg 

(更多iOS开发干货,欢迎关注 微博@iOS程序犭袁


Posted by 微博@iOS程序犭袁
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

About

最低只需传两个数组即可完成主流App框架搭建

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Objective-C 98.2%
  • Ruby 1.8%