自定义tabBarController
前言:
苹果官方已经提供我们很好用的工具栏系统的tabBar,可其对于项目的灵活需求还是有一定的局限性的,毕竟系统的UITabBarController的界面已经是系统固定,若想要满足用户体验比较好的产品需求的要求,则必须我们去自己定义tabBarController。好了,废话不多说,让我们开始吧。
界面展示:
(因为图片准备不是很好看,望大家见谅 ~ !~)
1.新建文件:新建一个继承于UITabBarController的控制器(我将它命名为WJTabBarController),以及继承于UITabBar的视图(我将它命名为WJTabBar)
2.给提供大家一个方便计算tabBar的Frame的类目: UIView+Frame
.h 文件
#import <UIKit/UIKit.h> @interface UIView (Frame) // 分类不能添加成员属性 // @property如果在分类里面,只会自动生成get,set方法的声明,不会生成成员属性,和方法的实现 @property (nonatomic, assign) CGFloat x; @property (nonatomic, assign) CGFloat y; @property (nonatomic, assign) CGFloat width; @property (nonatomic, assign) CGFloat height; @end
.m文件
#import "UIView+Frame.h" @implementation UIView (Frame) - (void)setX:(CGFloat)x { CGRect frame = self.frame; frame.origin.x = x; self.frame = frame; } - (CGFloat)x { return self.frame.origin.x; } - (void)setY:(CGFloat)y { CGRect frame = self.frame; frame.origin.y = y; self.frame = frame; } - (CGFloat)y { return self.frame.origin.y; } - (CGFloat)width { return self.frame.size.width; } - (void)setWidth:(CGFloat)width { CGRect frame = self.frame; frame.size.width = width; self.frame = frame; } - (CGFloat)height { return self.frame.size.height; } - (void)setHeight:(CGFloat)height { CGRect frame = self.frame; frame.size.height = height; self.frame = frame; } @end
3.为tabBarController做准备,先把TabBar的原型做出来: (类WJTabBar中)
.h文件下: 这里我使用了协议,实现在Controller中实现点击事件
#import <UIKit/UIKit.h> @class WJTabBar; @protocol WJTabBarDelegate <NSObject> /** * 点击中部按钮的时候调用 */ -(void)tabBarDidClickCenterButton:(WJTabBar *)tabBar; @end @interface WJTabBar : UITabBar @property (nonatomic, weak) id<WJTabBarDelegate>tabBarDelegate; //设置代理属性 @end
.m文件下:
#import "WJTabBar.h" #import "UIView+Frame.h" @interface WJTabBar () @property (nonatomic,weak) UIButton *centerButton; @end @implementation WJTabBar -(instancetype)initWithFrame:(CGRect)frame { if ([super initWithFrame:frame]) { //设置tabbar背景 [self setupBackground]; //添加中部按钮 [self setupCenterButton]; } return self; } -(void)setupBackground { self.backgroundColor = [UIColor whiteColor]; // [self setBackgroundImage:[UIImage imageNamed:@"background_tabbar"]]; } /** * 添加中部按钮 */ -(void)setupCenterButton { UIButton *centerButton = [UIButton buttonWithType:UIButtonTypeCustom]; [centerButton setBackgroundImage:[UIImage imageNamed:@"btn_一键百科_未选中"] forState:UIControlStateNormal]; [centerButton setBackgroundImage:[UIImage imageNamed:@"btn_一键百科_选中"] forState:UIControlStateHighlighted]; [centerButton addTarget:self action:@selector(centerButtonClick) forControlEvents:UIControlEventTouchUpInside]; [centerButton sizeToFit]; [self addSubview:centerButton]; self.centerButton = centerButton; } /** * 中部按钮的点击方法 */ -(void)centerButtonClick { if (_tabBarDelegate && [_tabBarDelegate respondsToSelector:@selector(tabBarDidClickCenterButton:)]) { [_tabBarDelegate tabBarDidClickCenterButton:self]; } } /** * 布局子控件 */ -(void)layoutSubviews { [self setupAllTabBarButtonsFrame]; } /** * 设置所以tabBarButton的frame */ -(void)setupAllTabBarButtonsFrame { int index = 0; for (UIView *tabBarButton in self.subviews) { // 如果不是UITabBarButton, 直接跳过 if (![tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue; // 根据索引调整位置 [self setupTabBarButtonFrame:tabBarButton atIndex:index]; // 索引增加 index++; } } /** * 设置摸个按钮的frame * * @param tabBarButton 需要设置的按钮 * @param index 按钮所在的index */ - (void)setupTabBarButtonFrame:(UIView *)tabBarButton atIndex:(int)index { CGFloat buttonW = self.width / (self.items.count + 1); CGFloat buttonH = self.height; tabBarButton.width = buttonW; tabBarButton.height = buttonH; if (index >= 2) { tabBarButton.x = buttonW * (index + 1); } else { tabBarButton.x = buttonW * index; } tabBarButton.y = 0; self.centerButton.center = CGPointMake(self.width * 0.5, self.height * 0.5); } @end
这样我们的WJTabBar就已经写好了
4.接下来就是我们的WJTabBarController:
.h文件下:
#import <UIKit/UIKit.h> @interface WJTabBarController : UITabBarController @end
.m文件下:
#import "WJTabBarController.h" #import "WJTabBar.h" @interface WJTabBarController () <WJTabBarDelegate> @property (nonatomic,strong) WJTabBar *customTabBar; @end @implementation WJTabBarController - (void)viewDidLoad { [super viewDidLoad]; //自定义tabBar [self setupTabBar]; // 添加所有子控制器 [self setUpAllChildViewController]; } /** * 添加所有子控制器 */ -(void)setUpAllChildViewController { //发现 UIViewController *mainVC = [[UIViewController alloc] init]; [self setupOneChildVC:mainVC title:@"首页" imageName:@"icon_首页_未选中" selectedImageName:@"icon_首页_选中"]; //淘淘淘 UIViewController *shopVC = [[UIViewController alloc] init]; [self setupOneChildVC:shopVC title:@"商城" imageName:@"icon商城_未选中" selectedImageName:@"btn_商城_选中"]; shopVC.view.backgroundColor = [UIColor purpleColor]; //子商城 UIViewController *cartVC = [[UIViewController alloc] init]; [self setupOneChildVC:cartVC title:@"购物车" imageName:@"icon_购物车_未选中" selectedImageName:@"btn_购物车_选中"]; cartVC.view.backgroundColor = [UIColor cyanColor]; //我的 UIViewController *mineVC = [[UIViewController alloc] init]; [self setupOneChildVC:mineVC title:@"我的" imageName:@"icon_个人中心_未选中" selectedImageName:@"btn_个人中心_选中"]; mineVC.view.backgroundColor = [UIColor whiteColor]; } - (void)setupOneChildVC:(UIViewController *)VC title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName { //1.设置tabBarItem //设置标题 VC.title = title; // 设置图片 VC.tabBarItem.image = [UIImage imageNamed:imageName]; // 如果是iOS7以上, 不需要渲染图片 VC.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImageName] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; // 设置tabBarItem的普通文字颜色 NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary]; textAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:0.475 green:0.475 blue:0.475 alpha:1]; textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:10]; [VC.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal]; // 设置tabBarItem的选中文字颜色 NSMutableDictionary *selectedTextAttrs = [NSMutableDictionary dictionary]; selectedTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:17/255.0 green:126/255.0 blue:146/255.0 alpha:1]; [VC.tabBarItem setTitleTextAttributes:selectedTextAttrs forState:UIControlStateSelected]; UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:VC]; [self addChildViewController:navi]; } /** * 自定义tabBar */ -(void)setupTabBar { self.customTabBar = [[WJTabBar alloc] init]; _customTabBar.tabBarDelegate = self; //更换系统自带的tabBar [self setValue:self.customTabBar forKeyPath:@"tabBar"]; //这里利用KVC的方式去更换系统的tabBar 因为系统上的tabBar是readonly属性 } /** * 实现tabBar中间按钮的点击事件 */ -(void)tabBarDidClickCenterButton:(WJTabBar *)tabBar { NSLog(@"%s",__func__); } @end