最近在寫一個需求,自定義TabBar旗们,自定義TabBar一般有兩種方式:
- ① 創(chuàng)建一個類繼承系統(tǒng)的UITabBar,在layoutSubviews方法中重新調(diào)整按鈕的位置,再通過[self setValue:tabBar forKeyPath:@"tabBar"]方法丰刊,利用KVC設(shè)置TabBar,但是iOS 13后蘋果粑粑不鼓勵使用KVC增拥;
- ② 創(chuàng)建一個繼承UIView的類YBTabBar啄巧,然后把系統(tǒng)UITabBar上的UITabBarItem移除,然后把YBTabBar加到系統(tǒng)TabBar的位置上掌栅;
鑒于第二種繼承UIView的方式更靈活且我們的tabbar還有一種類似漂浮的效果秩仆,所以這里我選用的是第二種方式,效果如下所示:
一猾封、TabBar實現(xiàn)
其實就是自定義個UIView澄耍,然后布局5個按鈕,核心代碼如下所示:
- (void)addTabBarButtonNorImageUrl:(NSString *)norImageUrl
selImageUrl:(NSString *)selImageUrl
title:(NSString *)title {
// 1.創(chuàng)建按鈕
YBTabBarButton *tabBarBtn = [[YBTabBarButton alloc] init];
tabBarBtn.delegate = self;
[self addSubview:tabBarBtn];
// 2.設(shè)置數(shù)據(jù)
[tabBarBtn setTabBarImageUrl:norImageUrl title:title];
// 3.監(jiān)聽按鈕點擊
[tabBarBtn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];
// 4.將自定義的YBTabBarButton對象
[self.tabbarBtnArray addObject:tabBarBtn];
[self.norImageArrM addObject:norImageUrl];
[self.selImageArrM addObject:selImageUrl];
// 5.默認選中第0個按鈕
if (self.tabbarBtnArray.count == 1) {
[self buttonClick:tabBarBtn];
[tabBarBtn.iconBtn setSelected:YES];
}
}
- (void)layoutSubviews {
[super layoutSubviews];
// 按鈕的frame數(shù)據(jù)
CGFloat buttonH = self.frame.size.height;
CGFloat buttonW = self.frame.size.width / self.tabbarBtnArray.count;
CGFloat buttonY = 0;
for (int index = 0; index < self.tabbarBtnArray.count; index++) {
// 1.取出按鈕
YBTabBarButton *button = self.tabbarBtnArray[index];
// 2.設(shè)置按鈕的frame
CGFloat buttonX = index * buttonW;
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
// 3.綁定tag
button.tag = index;
}
}
二晌缘、再自定義一個繼承系統(tǒng)的UITabBarController齐莲,
將系統(tǒng)的UITabBarItem移除,防止重影磷箕,然后將自定義UIView加到UITabBar选酗。核心代碼如下所示:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 初始化tabbar
[self setupTabbar];
// 初始化所有的子控制器
[self setupAllChildViewControllers];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// 刪除系統(tǒng)自動生成的UITabBarButton
for (UIView *child in self.tabBar.subviews) {
if ([child isKindOfClass:[UIControl class]]) {
[child removeFromSuperview];
}
}
}
- (void)setupTabbar {
//配置信息
YBConfig *config = [YBConfig shareInstance];
//config.titleFont = 12;
//config.norTitleColor = [UIColor blackColor];
//config.selTitleColor = [UIColor cyanColor];
//config.titleOffset = 5;
//config.imageOffset = 10;
//config.imageSize = CGSizeMake(50, 50);
//config.titleHeight = 12;
//config.bgImageOffset = 20;
YBTabBar *customTabBar = [[YBTabBar alloc] initWithFrame:self.tabBar.bounds config:config];
customTabBar.backgroundColor = [UIColor clearColor];
CGRect mainFrame = customTabBar.frame;
mainFrame.size.height = 88;
customTabBar.frame = mainFrame;
customTabBar.delegate = self;
[self.tabBar addSubview:customTabBar];
[customTabBar bringSubviewToFront:self.tabBar];
self.customTabBar = customTabBar;
}
/**
* 監(jiān)聽tabbar按鈕的改變
* @param from 原來選中的位置
* @param to 最新選中的位置
*/
- (void)ybTabBar:(YBTabBar *)tabBar didSelectedButtonFrom:(NSInteger)from to:(NSInteger)to {
self.selectedIndex = to;
NSLog(@"----from:%ld, to:%ld ",from,to);
}
- (void)setupAllChildViewControllers {
// 1.首頁
UIViewController *home = [[UIViewController alloc] init];
home.view.backgroundColor = [UIColor redColor];
[self setupChildViewController:home title:@"首頁" imageName:@"shouye" selectedImageName:@"shouye_s"];
// 2.消息
UIViewController *message = [[UIViewController alloc] init];
message.view.backgroundColor = [UIColor orangeColor];
[self setupChildViewController:message title:@"消息" imageName:@"quanzi" selectedImageName:@"quanzi_s"];
// 3.首頁
UIViewController *home1 = [[UIViewController alloc] init];
home1.view.backgroundColor = [UIColor blueColor];
[self setupChildViewController:home1 title:@"發(fā)現(xiàn)" imageName:@"shouye" selectedImageName:@"shouye_s"];
// 4.消息
UIViewController *message1 = [[UIViewController alloc] init];
message1.view.backgroundColor = [UIColor greenColor];
[self setupChildViewController:message1 title:@"廣場" imageName:@"quanzi" selectedImageName:@"quanzi_s"];
}
/**
* 初始化一個子控制器
*
* @param childVc 需要初始化的子控制器
* @param title 標(biāo)題
* @param imageName 圖標(biāo)
* @param selectedImageName 選中的圖標(biāo)
*/
- (void)setupChildViewController:(UIViewController *)childVc title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName {
// 1.設(shè)置控制器的屬性
childVc.title = title;
// 設(shè)置圖標(biāo)
childVc.tabBarItem.image = [UIImage imageNamed:imageName];
// 設(shè)置選中的圖標(biāo)
UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
childVc.tabBarItem.selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
childVc.tabBarItem.selectedImage = selectedImage;
// 2.包裝一個導(dǎo)航控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:childVc];
[self addChildViewController:nav];
// 3.添加tabbar內(nèi)部的按鈕
[self.customTabBar addTabBarButtonNorImageUrl:imageName
selImageUrl:selectedImageName
title:title];
}