前言:
苹果官方已经提供我们很好用的工具栏系统的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