iOS開發之自定義TabBar


對於UITabBarController, 大家都不陌生, 但是有時候又不那么的熟悉, 下面就來再認識一下這個熟悉的陌生人.

以下使用微信的tabBar圖標;

一. 系統UITabBarController基本使用

1.1 基本用法

UITabBarController的使用, 其實很簡單, 這里直接給出相應代碼:

APPTabBar.h

#import "APPTabBar.h" 

@implementation APPTabBar

+ (UIViewController *)showTabBar {

// 初始化UITabBarController實例對象
UITabBarController *tabBar = [[UITabBarController alloc]init];
// 創建子控制器
UIViewController *vc1 = [[UIViewController alloc]init];
vc1.view.backgroundColor = [UIColor redColor];
// 設置標題
vc1.tabBarItem.title = @"微信";
// 設置選中狀態的圖片
vc1.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_mainframeHL"];
// 設置未選中狀態的圖片
vc1.tabBarItem.image = [UIImage imageNamed:@"tabbar_mainframe"] ;
// 設置右上角顯示數字(例如: 未讀消息數目)
vc1.tabBarItem.badgeValue = @"100";
// 右上角數字背景色
vc1.tabBarItem.badgeColor = [UIColor greenColor];

UIViewController *vc2 = [[UIViewController alloc]init];
vc2.view.backgroundColor = [UIColor orangeColor];
vc2.tabBarItem.title = @"聯系人";
vc2.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_contactsHL"];
vc2.tabBarItem.image = [UIImage imageNamed:@"tabbar_contacts"];

UIViewController *vc3 = [[UIViewController alloc]init];
vc3.view.backgroundColor = [UIColor cyanColor];
vc3.tabBarItem.title = @"發現";
vc3.tabBarItem.image = [UIImage imageNamed:@"tabbar_discover"];
vc3.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_discoverHL"];

UIViewController *vc4 = [[UIViewController alloc]init];
vc4.view.backgroundColor = [UIColor whiteColor];
vc4.tabBarItem.title = @"";
vc4.tabBarItem.image = [UIImage imageNamed:@"tabbar_me"];
vc4.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_meHL"];

// 添加子視圖到tabbar
tabBar.viewControllers = @[vc1, vc2, vc3, vc4];

return tabBar;
}

AppDelegate.m 

#import "AppDelegate.h"
#import "APPTabBar.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor redColor];
    self.window.rootViewController = [APPTabBar showTabBar];
    [self.window makeKeyAndVisible];
    return YES;
}


效果如下:



注意:這里使用的是微信的圖標, 是綠色的, 設置完后變成了藍色, 而且上面也沒有設置選中及未選中文字的顏色, 這里都被默認設置了, 最主要的是沒有顯示我原先圖標的顏色.( 這樣美工是不同意的).

1.2. 顯示原圖

根據上面的問題, 我們先來看看圖標的問題, 為了不被系統渲染成藍色, 這里我們在設置各個控制器的選中和未選中的圖標的時候, 調用一下UIImage的這個方法即可imageWithRenderingMode:

// 設置選中狀態的圖片
vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"tabbar_mainframeHL"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 設置未選中狀態的圖片
vc1.tabBarItem.image = [[UIImage imageNamed:@"tabbar_mainframe"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

這樣就能正確顯示我們原先的圖片了;

1.3 修改文字顏色

但是文字的顏色並不是我們需要的, 我們可以通過下面的方法, 來修改文字的顏色:

// 未選中狀態下文字顏色
[vc1.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor redColor]} forState:UIControlStateNormal];
// 選中狀態下的文字顏色
[vc1.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor blueColor]} forState:UIControlStateSelected];

這是設置選中和未選中狀態下的標題屬性, 效果如下:


這里我只是修改了前兩個控制器的文字, 后面的還是用的默認的.
上面是修改按鈕標題的文字屬性, 按鈕右上角的角標的文字屬性, 可使用下面的方法來修改:

// 未選中狀態下的角標文字顏色
[vc1.tabBarItem setBadgeTextAttributes:@{NSForegroundColorAttributeName: [UIColor blackColor]} forState:UIControlStateNormal];
// 選中狀態下的角標文字顏色
[vc1.tabBarItem setBadgeTextAttributes:@{NSForegroundColorAttributeName: [UIColor orangeColor]} forState:UIControlStateSelected];

 

以上就是系統自帶UITabBarController及相關屬性的設置, 對於圖標規則的需求基本都能滿足, 如果還有其他的需求, 系統不能滿足的, 就只能自定義了.

二. 自定義tabBarController

對於自定義的tabBar, 我們一般還是定義為UITabBarController的子類:

@interface LXTabBarController : UITabBarController

這樣我們可以借助UITabBarController的一些屬性和方法, 例如切換控制器; 不用再去寫切換的邏輯;
實際上, 我們說的自定義的tabBar, 對數情況下是自定義的底部的tabBar; 所以, 我們的重點是來設置底部視圖的實現.
我們自定義的時候, 一般有兩種選擇:
- 一種是, 隱藏掉系統的tabBar, 完全重新布局;
- 另一種是, 使用系統的tabBar, 但是自定義tabBarItem

不管是哪一種, 都需要自定義一個tabBarItem, 所以, 先來看看怎么定義這個tabBarItem;

2.1 自定義item –LXTabBarItem

這個類, 主要做的是布局item, 及響應點擊事件
我們定義一個類" LXTabBarItem ", 繼承自UIView, .h聲明文件如下:

//
// LXTabBarItem.h
// LXTabBarController
//
// Created by LXL on 2018/12/9.
// Copyright © 2018年 LXL. All rights reserved.
//

@protocol LXTabBarItemDelegate;
@interface LXTabBarItem : UIView

@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) UIColor *titleColor;

@property (nonatomic, assign) id <LXTabBarItemDelegate> delegate;
@end

@protocol LXTabBarItemDelegate <NSObject>

- (void)tabBarItem:(LXTabBarItem *)item didSelectIndex:(NSInteger)index;
@end

這里使用代理來回調點擊事件; .m實現如下:

//
// LXTabBarItem.m
// LXTabBarController
//
// Created by LXL on 2018/12/9.
// Copyright © 2018年 LXL. All rights reserved.
//

#import "LXTabBarItem.h"

static NSInteger defaultTag = 100000;
@interface LXTabBarItem ()

@property (nonatomic, strong)UIImageView *iconImageView;
@property (nonatomic, strong)UILabel *titleLabel;
@end

@implementation LXTabBarItem
- (instancetype)init {
  self = [super init];
  if (self) {

  self.userInteractionEnabled = YES;
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(itemClicked:)];
  [self addGestureRecognizer:tap];
}

  return self;
}
// 重寫setTag方法
- (void)setTag:(NSInteger)tag {

  [super setTag:tag + defaultTag];
}

- (UIImageView *)iconImageView {
  if (_iconImageView == nil) {
    _iconImageView = [[UIImageView alloc]init];
    _iconImageView.contentMode = UIViewContentModeScaleAspectFit;
    [self addSubview:_iconImageView];
  }

  return _iconImageView;
}

- (UILabel *)titleLabel {
  if (_titleLabel == nil) {
    _titleLabel = [[UILabel alloc]init];
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    _titleLabel.font = [UIFont systemFontOfSize:10];
    _titleLabel.numberOfLines = 0;
    _titleLabel.textColor = [UIColor grayColor];
   [self addSubview:_titleLabel];
}

  return _titleLabel;
}

- (void)setIcon:(NSString *)icon {
  _icon = icon;

  self.iconImageView.image = [UIImage imageNamed:icon];

}

- (void)setTitle:(NSString *)title {
  _title = title;

  self.titleLabel.text = title;
}

- (void)setTitleColor:(UIColor *)titleColor {
  _titleColor = titleColor;

  self.titleLabel.textColor = titleColor;
}
- (void)layoutSubviews {
  [super layoutSubviews];

  CGFloat space = 6.0;

  if (self.icon.length > 0 && self.title.length > 0) {

    CGFloat iconHeight = (CGRectGetHeight(self.frame) - space * 3)*2/3.0 ;
    self.iconImageView.frame = CGRectMake(space, space, CGRectGetWidth(self.frame) - 2 * space, iconHeight);
    self.titleLabel.frame = CGRectMake(space, CGRectGetMaxY(self.iconImageView.frame) + space, CGRectGetWidth(self.frame) - 2*space,     iconHeight/2.0);
  } else if (self.icon.length > 0) {

    self.iconImageView.frame = CGRectMake(2, 2, CGRectGetWidth(self.frame) - 4, CGRectGetHeight(self.frame) - 4);
  } else if (self.title.length > 0) {

    self.titleLabel.frame = CGRectMake(2, CGRectGetHeight(self.frame) - 22, CGRectGetWidth(self.frame) - 4, 20);
  }
}

- (void)itemClicked:(UITapGestureRecognizer *)tap {

  if (self.delegate && [self.delegate respondsToSelector:@selector(tabBarItem:didSelectIndex:)]) {

    [self.delegate tabBarItem:self didSelectIndex:self.tag - defaultTag];
  }
}


/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/

@end

其實, 很簡單, 只是添加了一個imageView, 一個label, 和一個單擊手勢來響應點擊事件. 這里我是在* layoutSubviews*方法里來布局子視圖的, 這樣當視圖frame改變的時候, 其子視圖會做相應的調整;
這樣,tabBarItem的自定義就完成了,接下來就是自定義tabBar;
tabBar的定義, 有兩種方法:
- 一個是繼承自UIView, 完全自定義;
- 一個是繼承自UITabBar;

2.2 繼承自UIView

先來看一下繼承自UIView, 完全自定義的方法:

//
// LXTabBar.h
// LXTabBarController
//
// Created by LXL on 2018/12/9.
// Copyright © 2018年 LXL. All rights reserved.
//

#import <UIKit/UIKit.h>

@class LXTabBarItem;
@protocol LXTabBarDelegate;
@interface LXTabBar : UIView

@property (nonatomic, strong)NSArray<LXTabBarItem *> *items;
@property (nonatomic, assign)id <LXTabBarDelegate> delegate;
@end

@protocol LXTabBarDelegate <NSObject>

- (void)tabBar:(LXTabBar *)tab didSelectItem:(LXTabBarItem *)item atIndex:(NSInteger)index ;
@end

這里是.h文件內容, 其屬性比較簡單, 只設置了delegate和items;
.m的實現如下:

//
// LXTabBar.m
// LXTabBarController
//
// Created by LXL on 2018/12/9.
// Copyright © 2018年 LXL. All rights reserved.
//

#import "LXTabBar.h"
#import "LXTabBarItem.h"

@interface LXTabBar ()<LXTabBarItemDelegate>

@property (nonatomic, strong) UIVisualEffectView *effectView;
@property (nonatomic, strong) UIView *topLine;
@end
@implementation LXTabBar

- (instancetype)init {
  self = [super init];
  if (self) {

    self.backgroundColor = [UIColor whiteColor];
  }

  return self;
}
- (UIView *)topLine {
  if (_topLine == nil) {
    _topLine = [[UIView alloc]init];
    _topLine.backgroundColor = [UIColor grayColor];
    [self addSubview:_topLine];
}

  return _topLine;
}

- (UIVisualEffectView *)effectView {
  if (_effectView == nil) {

    UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    _effectView = [[UIVisualEffectView alloc] initWithEffect:effect];
    _effectView.alpha = 1.0;
    [self addSubview:_effectView];
  }

    return _effectView;
}

- (void)layoutSubviews {
  [super layoutSubviews];

  self.effectView.frame = self.bounds;

  [self setupItems];

  self.topLine.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), 0.6);
}

- (void)setupItems {

  CGFloat width = CGRectGetWidth(self.frame)/self.items.count;
  CGFloat height = CGRectGetHeight(self.frame);

  for (int i = 0; i < self.items.count; i++) {

    LXTabBarItem *item = [self.items objectAtIndex:i];
    item.frame = CGRectMake(i*width, 0, width, height);
    [self addSubview:item];
    item.delegate = self;
  }
}

- (void)tabBarItem:(LZTabBarItem *)item didSelectIndex:(NSInteger)index {

  if (self.delegate && [self.delegate respondsToSelector:@selector(tabBar:didSelectItem:atIndex:)]) {

    [self.delegate tabBar:self didSelectItem:item atIndex:index];
  }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
  // Drawing code
}
*/

@end

這個類的主要作用是: 布局各個item, 在tabBar的位置, 及tabBar的一些內容.
接下來, 就是定義LXTabBarController了;

2.3 自定義LXTabBarController

這個類的主要作用是: 提供數據源, 繪制底部tabBar, 及關聯viewController;
在提供數據的時候, 我單獨設置了一個類類儲存這些數據, 而沒有直接設置為" LXTabBarController "的屬性:

#pragma mark - LXTabBarConfig
@interface LXTabBarConfig : NSObject

/**
控制器數組, 必須設置
*/
@property (nonatomic, strong) NSArray *viewControllers;

/**
item標題數組, 選擇設置
*/
@property (nonatomic, strong) NSArray *titles;

/**
是否是導航, 默認 YES
*/
@property (nonatomic, assign) BOOL isNavigation;

/**
選中狀態下的圖片數組
*/
@property (nonatomic, strong) NSArray *selectedImages;

/**
正常狀態下的圖片數組
*/
@property (nonatomic, strong) NSArray *normalImages;

/**
選中狀態下的標題顏色 默認: red
*/
@property (nonatomic, strong) UIColor *selectedColor;

/**
正常狀態下的標題顏色 默認: gray
*/
@property (nonatomic, strong) UIColor *normalColor;
@end

提供數據源的時候, 只需要配置這個config即可;
其.m文件, 只是設置了一些默認值:

@implementation LXTabBarConfig
- (instancetype)init {
  self = [super init];
  if (self) {

    _isNavigation = YES;
    _normalColor = [UIColor grayColor];
    _selectedColor = [UIColor redColor];
  }

  return self;
}
@end

下面, 回到" LXTabBarController ", 其.h的聲明, 就簡潔許多:

#import <UIKit/UIKit.h>

@class LXTabBarConfig;
typedef LXTabBarConfig*(^tabBarBlock)(LXTabBarConfig *config);
@interface LXTabBarController : UITabBarController

/**
是否可用自動旋轉屏幕
*/
@property (nonatomic, assign) BOOL isAutoRotation;

/**
創建tabBarController

@param block 配置創建tabBarController所需的參數
@return 返回tabBarController實例對象
*/
+ (instancetype)createTabBarController:(tabBarBlock)block;

/**
獲取當前的tabBarController實例, 實例創建后可通過此方法獲取當前實例

@return 返回tabBarController實例對象
*/
+ (instancetype)defaultTabBarController;

/**
隱藏底部tabBar的方法

@param isAnimation 是否需要動畫
*/
- (void)hiddenTabBarWithAnimation:(BOOL)isAnimation;

/**
顯示底部tabBar的方法

@param isAnimation 是否需要動畫
*/
- (void)showTabBarWithAnimation:(BOOL)isAnimation;
@end

只是提供了創建的方法, 及獲取當前實例和隱藏/顯示底部tabBar的方法;
.m中的實現:

//
// LXTabBarController.m
// LXTabBarController
//
// Created by LXL on 2018/12/9.
// Copyright © 2019年 LXL. All rights reserved.
//

#import "LXTabBarController.h"
#import "LXTabBar.h"

static CGFloat lxTabBarHeight = 49.0;
@interface LXTabBarController ()<LXTabBarDelegate>

@property (nonatomic, strong) LXTabBar *customTabBar;
@property (nonatomic, strong) LXTabBarConfig *config;
@end

@implementation LXTabBarController
- (LXTabBar *)customTabBar {

if (_customTabBar == nil) {
  _customTabBar = [[LXTabBar alloc]init];
  _customTabBar.delegate = self;
}

  return _customTabBar;
}

+ (instancetype)createTabBarController:(tabBarBlock)block {
  static dispatch_once_t onceToken;
  static LXTabBarController *tabBar;
  dispatch_once(&onceToken, ^{

  tabBar = [[LXTabBarController alloc]initWithBlock:block];
});

  return tabBar;
}

+ (instancetype)defaultTabBarController {

  return [LXTabBarController createTabBarController:nil];
}

- (void)hiddenTabBarWithAnimation:(BOOL)isAnimation {

  if (isAnimation) {

    [UIView animateWithDuration:0.2 animations:^{

    self.customTabBar.alpha = 0;
    }];
  } else {

  self.customTabBar.alpha = 0;
  }
}

- (void)showTabBarWithAnimation:(BOOL)isAnimation {

  if (isAnimation) {

    [UIView animateWithDuration:0.2 animations:^{

    self.customTabBar.alpha = 1.0;
    }];
  } else {

    self.customTabBar.alpha = 1.0;
  }
}

- (instancetype)initWithBlock:(tabBarBlock)block {

   self = [super init];
   if (self) {

    LXTabBarConfig *config = [[LXTabBarConfig alloc]init];

    NSAssert(block, @"Param in zhe function, can not be nil");
    if (block) {

    _config = block(config);
}

NSAssert(_config.viewControllers, @"Param 'viewControllers' in the 'config', can not be nil");
[self setupViewControllers];
[self setupTabBar];

_isAutoRotation = YES;
}

return self;
}

- (void)setupViewControllers {

  if (_config.isNavigation) {

    NSMutableArray *vcs = [NSMutableArray arrayWithCapacity:_config.viewControllers.count];
  for (UIViewController *vc in _config.viewControllers) {
    if (![vc isKindOfClass:[UINavigationController class]]) {
      UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
      [vcs addObject:nav];
    } else {
      [vcs addObject:vc];
  }
}

  self.viewControllers = [vcs copy];
  } else {

  self.viewControllers = [_config.viewControllers copy];
  }
}

- (void)setupTabBar {

  NSMutableArray *items = [NSMutableArray array];
  for (int i = 0; i < _config.viewControllers.count; i++) {
    LXTabBarItem *item = [[LXTabBarItem alloc]init];

  if (i == 0) {

    item.icon = _config.selectedImages[i];
    if (_config.titles.count > 0) {
      item.titleColor = _config.selectedColor;
    }
  } else {

    item.icon = _config.normalImages[i];
  if (_config.titles.count > 0) {

    item.titleColor = _config.normalColor;
  }

}
if (i < _config.titles.count) {

  item.title = _config.titles[i];
}

[items addObject:item];
item.tag = i;
}
// 隱藏掉系統的tabBar
self.tabBar.hidden = YES;
self.customTabBar.items = [items copy];
self.customTabBar.frame = CGRectMake(0, CGRectGetHeight(self.view.frame) - lxTabBarHeight, CGRectGetWidth(self.view.frame), lxTabBarHeight);
[self.view addSubview:self.customTabBar];
}

- (void)viewDidLoad {
  [super viewDidLoad];
// Do any additional setup after loading the view.

self.view.backgroundColor = [UIColor whiteColor];
self.selectedIndex = 0;
}

#pragma mark - LXTabBarDelegate
- (void)tabBar:(LXTabBar *)tab didSelectItem:(LXTabBarItem *)item atIndex:(NSInteger)index {

  NSMutableArray *items = [NSMutableArray arrayWithCapacity:0];
  for (UIView *view in tab.subviews) {
    if ([view isKindOfClass:[LXTabBarItem class]]) {

    [items addObject:view];
  }
}

for (int i = 0; i < items.count; i++) {

  UIView *view = items[i];
  if ([view isKindOfClass:[LXTabBarItem class]]) {
    LXTabBarItem *item = (LXTabBarItem *)view;
    item.icon = self.config.normalImages[i];
    if (self.config.titles.count > 0) {

      item.titleColor = _config.normalColor;
    }

  }
}

item.icon = self.config.selectedImages[index];

if (self.config.titles.count > 0) {

  item.titleColor = self.config.selectedColor;
}

  self.selectedIndex = index;
}

// 屏幕旋轉時調整tabbar
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {

  [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

  self.customTabBar.frame = CGRectMake(0, size.height - lxTabBarHeight, size.width, lxTabBarHeight);
}

- (BOOL)shouldAutorotate {

  return self.isAutoRotation;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
  if (self.isAutoRotation) {

    return UIInterfaceOrientationMaskAllButUpsideDown;
  } else {

    return UIInterfaceOrientationMaskPortrait;
  }
}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/

@end

這里主要的其實就是, * setupTabBar*方法
和* LXTabBarDelegate*的代理方法tabBar:(LXTabBar )tab didSelectItem:(LXTabBarItem )item atIndex:(NSInteger)index, 需要處理一些狀態的轉換;
到此, 第一種的自定義就結束了, 效果如下:

 

需要注意的是:
因為我們自定義了tabBar , 所以控制器的屬性hidesBottomBarWhenPushed 就失去效果了, 解決的方法可以是在合適的地方來調用隱藏/顯示的方法;
如果, 還想使用系統的* hidesBottomBarWhenPushed*效果, 可在使用的時候, 調整一下方法:一般, 我們是直接將tabBarController作為window的rootvc, 然后在其子控制器分別加上導航, 我們可以做如下調整:
將tabBar作為UINavigationController的rootvc, 然后把這個導航作為window的rootvc:

// 為了能夠使用hidesBottomBarWhenPushed, 不直接把tabBar設置為window的跟視圖, 而是設置為導航的rootvc, 然后把導航設置為window的跟視圖
// 這樣, 在子控制器上就不用再添加導航了, 即設置: config.isNavigation = NO;
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:tab];
// 打開hidesBottomBarWhenPushed
nav.hidesBottomBarWhenPushed = YES;
self.window.rootViewController = nav;

這樣做, 需要注意的是, 其子控制器就不用再添加導航了.

這樣, 就會有上面Gif的效果;
demo地址: LXTabBarController

2.4 繼承自UITabBar

繼承自UITabBar的方式, 與繼承自UIView, 主要的區別是LZTabBar的內容, 其他如LXTabBarItem 和LXTabBarController相關邏輯都是一樣的;

#import <UIKit/UIKit.h>

@class LXTabBarItem;
@protocol LXTabBarDelegate;
@interface LXTabBar : UITabBar

@property (nonatomic, strong)NSArray<LXTabBarItem *> *lzItems;
@property (nonatomic, assign)id <LXTabBarDelegate> lzDelegate;
@end

@protocol LXTabBarDelegate <NSObject>

- (void)tabBar:(LXTabBar *)tab didSelectItem:(LXTabBarItem *)item atIndex:(NSInteger)index ;

@end

.m的實現中, 主要是將系統的item移除掉, 然后添加上自定義的item:

#import "LXTabBar.h"

@interface LXTabBar ()<LXTabBarItemDelegate>

@end
@implementation LXTabBar

- (instancetype)init {
  self = [super init];
  if (self) {

    self.backgroundColor = [UIColor whiteColor];
  }
  return self;
}

- (void)layoutSubviews {
[super layoutSubviews];

// 移除系統的tabBarItem
Class class = NSClassFromString(@"UITabBarButton");
for (UIView *item in self.subviews) {
  if ([item isKindOfClass:class]) {
    [item removeFromSuperview];
  }
}
// 設置自定義的tabBarItem
[self setupItems];
}

- (void)setupItems {

CGFloat width = CGRectGetWidth(self.frame)/self.items.count;
CGFloat height = CGRectGetHeight(self.frame);

  for (int i = 0; i < self.lzItems.count; i++) {

    LXTabBarItem *item = [self.lzItems objectAtIndex:i];
    item.frame = CGRectMake(i*width, 0, width, height);
    [self addSubview:item];
    item.delegate = self;
  }
}

- (void)tabBarItem:(LZTabBarItem *)item didSelectIndex:(NSInteger)index {

  if (self.lzDelegate && [self.lzDelegate respondsToSelector:@selector(tabBar:didSelectItem:atIndex:)]) {

    [self.lzDelegate tabBar:self didSelectItem:item atIndex:index];
  }
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/

@end

其最終的效果是一樣的, 只不過我們可以在執行push操作的時候使用控制器的* hidesBottomBarWhenPushed*屬性來隱藏底部的tabBar;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM