前言-從問題開始##
為什么要自定義UITabBarController?
原因:系統(tǒng)的UITabBarController控制器有一定的局限性,如果需求想要加一些動畫效果,那么系統(tǒng)實現(xiàn)就有點困難。況且我認(rèn)為每個developer都應(yīng)該有自己的一套自定義UI控件,以便于在項目把時間花費在重要的邏輯業(yè)務(wù)和細節(jié)處理上。
怎樣自定義UITabBarController?##
方法:模擬系統(tǒng)的UITabBarController
主要結(jié)構(gòu):

系統(tǒng)的結(jié)構(gòu)圖.png

自定義tabBar結(jié)構(gòu).png
自定義控制器包括:內(nèi)容View + tabBar(每個item組成)

View的層級結(jié)構(gòu).png
主要思路:
1、API入口
A、設(shè)置子控制器
@property (nonatomic, strong) NSArray <UIViewController *>*viewControllers;
B、也可以設(shè)置每個ViewController的lzb_tabBarItem
@property(nonatomic, strong) LZBTabBarItem *lzb_tabBarItem;
設(shè)置子控制器數(shù)組
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers
{
if(viewControllers.count == 0) return;
//移除之前的
for (UIViewController *viewController in _viewControllers)
{
//注意:在removeFromParentViewController必須先調(diào)用willMoveToParentViewController
[viewController willMoveToParentViewController:nil];
[viewController.view removeFromSuperview];
[viewController removeFromParentViewController];
}
_viewControllers = viewControllers;
NSMutableArray *tabBarItems = [NSMutableArray array];
for (UIViewController *viewController in viewControllers) {
LZBTabBarItem *tabBarItem = [[LZBTabBarItem alloc] init];
[tabBarItems addObject:tabBarItem];
[tabBarItem setTitle:viewController.title];
viewController.lzb_tabBarController = self;
}
[self.tabbar setItems:tabBarItems];
}
2、點擊事件,通過代理進行事件傳遞
點擊item調(diào)用
- (void)tabbarItemDidSelected:(LZBTabBarItem *)item
{
if(![self.items containsObject:item]) return;
NSInteger index = [self.items indexOfObject:item];
if([self.delegate respondsToSelector:@selector(lzb_tabBar:shouldSelectItemAtIndex:)])
{
if(![self.delegate lzb_tabBar:self shouldSelectItemAtIndex:index])
return;
}
self.currentSelectItem = item;
if([self.delegate respondsToSelector:@selector(lzb_tabBar:didSelectItemAtIndex:)])
{
[self.delegate lzb_tabBar:self didSelectItemAtIndex:index];
}
}
控制器成為代理,實現(xiàn)代理方法
- (BOOL)lzb_tabBar:(LZBTabBar *)tabBar shouldSelectItemAtIndex:(NSInteger)index
{
if (index < 0 || index >= self.viewControllers.count) return NO;
if([self.delegate respondsToSelector:@selector(lzb_tabBarController:shouldSelectViewController:)])
{
if(![self.delegate lzb_tabBarController:self shouldSelectViewController:[self.viewControllers objectAtIndex:index]])
return NO;
}
if(self.selectedViewController == [self.viewControllers objectAtIndex:index])
{
if([self.selectedViewController isKindOfClass:[UINavigationController class]])
{
UINavigationController *selectViewControler = (UINavigationController *)self.selectedViewController;
//如果不是頂層控制器,就回到頂層
if(selectViewControler.topViewController != [selectViewControler.viewControllers objectAtIndex:0])
{
[selectViewControler popToRootViewControllerAnimated:YES];
}
}
return NO;
}
return YES;
}
- (void)lzb_tabBar:(LZBTabBar *)tabBar didSelectItemAtIndex:(NSInteger)index
{
if (index < 0 || index >= self.viewControllers.count) return;
[self setSelectedIndex:index animation:self.isShouldAnimation];
if([self.delegate respondsToSelector:@selector(lzb_tabBarController:didSelectViewController:)])
[self.delegate lzb_tabBarController:self didSelectViewController:[self.viewControllers objectAtIndex:index]];
}
詳情請直接下載demo查看:
自定義TabBarViewController-LZBTabbarViewController
怎樣使用自定義UITabBarController?##
使用非常簡單
1、一定要先設(shè)置控制器數(shù)組
@property (nonatomic, strong) NSArray <UIViewController *>*viewControllers;
2、可以單獨設(shè)置每個子控制器的的item
#pragma mark - config 文字樣式
/**
* 文字內(nèi)容
*/
@property (nonatomic, copy) NSString *title;
/**
* 文字偏移量
*/
@property (nonatomic, assign) UIOffset titleOffest;
/**
* 未選中文字屬性描述:顏色、字體
*/
@property (nonatomic, strong) NSDictionary *unselectTitleAttributes;
/**
* 選中文字屬性描述:顏色、字體
*/
@property (nonatomic, strong) NSDictionary *selectTitleAttributes;
#pragma mark - config 圖片樣式
/**
* 選中圖片
*/
@property (nonatomic, strong) UIImage *selectImage;
/**
* 未選中圖片
*/
@property (nonatomic, strong) UIImage *unSelectImage;
/**
* 圖片偏移量
*/
@property (nonatomic, assign) UIOffset imageOffest;
/**
設(shè)置選中和未選中的圖片
@param selectImage 選中圖片
@param unSelectImage 未選中圖片
*/
- (void)setSelectImage:(UIImage *)selectImage unselectImage:(UIImage *)unSelectImage;
#pragma mark - config 背景View圖片樣式
/**
* 選中背景圖片
*/
@property (nonatomic, strong) UIImage *selectBackgroundImage;
/**
* 未選中背景圖片
*/
@property (nonatomic, strong) UIImage *unselectBackgroundImage;
/**
設(shè)置背景選中和未選中的圖片
@param selectedImage 選中圖片
@param unselectedImage 未選中圖片
*/
- (void)setBackgroundSelectedImage:(UIImage *)selectedImage unselectedImage:(UIImage *)unselectedImage;
#pragma mark - config 角標(biāo)樣式
/**
* 角標(biāo)文字
*/
@property (nonatomic, copy) NSString *badgeValue;
/**
* 角標(biāo)背景圖片
*/
@property (nonatomic, strong) UIImage *badgeBackgroundImage;
/**
* 角標(biāo)背景顏色
*/
@property (nonatomic, strong) UIColor *badgeBackgroundColor;
/**
* 角標(biāo)文字顏色
*/
@property (nonatomic, strong) UIColor *badgeTextColor;
/**
* 角標(biāo)文字字體
*/
@property (nonatomic, strong) UIFont *badgeTextFont;
/**
* 角標(biāo)偏移量
*/
@property (nonatomic, assign) UIOffset badgeOffset;
/**
* 角標(biāo)背景偏移量
*/
@property (nonatomic, assign) UIOffset badgeBackgroundOffset;
效果展示##

LZBTabBarContoller.gif
詳情代碼請直接下載demo查看:
自定義TabBarViewController-LZBTabbarViewController
最后贈言###
star 是對我們程序猿最大的鼓勵