iOS開發中XIB實現自定義TabBar功能

iOS中定制tabBar,目前無非就兩種方式:

第一種是繼承系統的UITabBar,在子類里進行自定義修改,實例化之后利用KVC setTabBar: 即可
第二種是自定義View,創建若干個需要的按鈕,按鈕的點擊事件去Hook系統的TabBar Item的點擊事件,主要是系統的TabBarController的一個屬性,即selectedIndex 起到切換子控制器的作用,也就是說按鈕的選中事件和切換子控制器是一致的,利用下標去映射就ok啦

首先拿到問題,進行如下分析:

  • 1 自定義需要什么東西 ?
  • 2 需要實現什么樣的功能?
  • 3 代碼如何封裝,可復用性和穩定性更高?
  • 4 用什么方式實現的更優雅,更簡單可控

......



#1. 自定義需要準備好圖片(選中與常態下的兩套圖標)

#2. 有特殊需求的時候才需要特別定制,一般情況下監聽點擊事情,模仿系
#統切換子控制器的動作即可

#3. 一般會做成公共的API調用接口,如果是在系統的基礎上修改,
#使用代理無疑是更優雅的選擇,直接使用系統的代理, 如果是自定義的
#話,block和代理均可,個人比較傾向于使用代理

#4. 如果是繼承系統的UITabBar的基礎上進行修改的話,建議用純代碼,
#因為這樣修改起來比較方便, 對于自定義View的方式來定制的話,如果是
#簡單的監聽點擊或者不是什么復雜UI,我倒是覺得XIB也無傷大雅,怎么
#簡單怎么來,除非是情況比較復雜,那就只得純代碼來懟.
廢話不多說,進入正題,這里對于系統的UITabBar簡單定制不再作過多獒述,網上太多類似教程, 基本上是開箱即用

XIB定制 ----自定義View實現TabBar功能

拽UI

根據自己業務和UI進行拖拽

拉約束

只可意會,不可描述,拉得多了自然就會了

添加監聽事件

直接拖線就好辣,還講個鬼哦

處理點擊邏輯

判斷選中與未選中兩種狀態下的顯示邏輯

打通UITabBarController

selectedIndex 與 按鈕選中下標是一致的就ok??

文筆不好,老老實實做筆記,貼代碼大法

<!--- TabBar --->

@protocol WGBTabBarDelegate <NSObject>

- (void)selectedClickWithIndex:(NSInteger)index;

@end

@interface WGBTabBar : UIView

@property (nonatomic,weak) id<WGBTabBarDelegate> wgbDelegate;

@end


#import "WGBTabBar.h"

@interface WGBTabBar ()

@property (nonatomic,strong) UIButton *tempButton;

@property (weak, nonatomic) IBOutlet UIButton *oneButton;

@end

@implementation WGBTabBar

- (void)awakeFromNib{
    [super awakeFromNib];

     self.tempButton = self.oneButton;

}

    /// 0,1,2,3
- (IBAction)tabbarClickAction:(UIButton *)sender {

    sender.backgroundColor = [UIColor blueColor];
    self.tempButton.backgroundColor = [UIColor purpleColor];
    self.tempButton.selected = NO;
    self.tempButton = sender;


    if ([self.wgbDelegate respondsToSelector: @selector(selectedClickWithIndex:)]) {
        [self.wgbDelegate selectedClickWithIndex: sender.tag];
    }
}

@end


<!--- TabBarViewController --->
#import "WGBTabBarViewController.h"
#import "WGBTabBar.h"
#import "OneViewController.h"
#import "TwoViewController.h"
#import "ThreeViewController.h"
#import "FourViewController.h"

@interface WGBTabBarViewController ()<WGBTabBarDelegate>

@end

@implementation WGBTabBarViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self createTabBar];
    [self initViewContreollers];
}

- (void)createTabBar{
    CGFloat kWidth = [UIScreen mainScreen].bounds.size.width;
    CGFloat kHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat kTabBarHeight = 49;

    WGBTabBar *tabBar = [[NSBundle mainBundle] loadNibNamed:@"WGBTabBar" owner:nil options:0][0];
    tabBar.wgbDelegate = self;
    tabBar.frame = CGRectMake(0, kHeight - kTabBarHeight, kWidth , kTabBarHeight);
    self.tabBar.hidden = YES; ///這句代碼很關鍵 ,之前沒隱藏,總感覺有什么東西擋住
    [self.view addSubview: tabBar] ;
}

#pragma mark- <WGBTabBarDelegate>
- (void)selectedClickWithIndex:(NSInteger)index{
    self.selectedIndex = index;
}

- (void)initViewContreollers{
    OneViewController *oneVC = [[OneViewController alloc] init];
    TwoViewController *twoVC = [[TwoViewController alloc] init];
    ThreeViewController *threeVC = [[ThreeViewController alloc] init];
    FourViewController *fourVC = [[FourViewController alloc] init];
    NSArray *VCs = @[oneVC,twoVC,threeVC,fourVC];
    NSMutableArray *childsVC = [NSMutableArray array];
    for (UIViewController *VC in VCs) {
        UINavigationController *rootVC = [[UINavigationController alloc] initWithRootViewController:VC];
        VC.title = NSStringFromClass([VC class]);
        [childsVC addObject: rootVC];
    }
    self.viewControllers = childsVC;
}

@end

(Tips)注意:

系統的tabBar一定要隱藏掉,不然會干擾點擊事件,讓你產生錯覺,內部實現不隱藏的話應該是會放到最上層

做了一個最簡單的,沒有添加圖片,純文字表達一下意思咯,意思意思咯


Simulator Screen Shot 2017年7月3日 00.33.04.png

2017 年 07 月 12日 更新一個新姿勢

如何優雅的隱藏tabBar?

除了將自定義tabBar的hidden屬性提出來,似乎并沒有什么太好的方案. 而hook系統的"hidesBottomBarWhenPushed"屬性,這個需要繼承系統的UITabBar定制的才適用.
下面簡述一下我的做法
#1. 將自定義view(即tabBar) 的hidden屬性提取出來,可以通過Appdelegate 做成全局的屬性
#2. 在基類里定義一個屬性,hideTabBar,用于獲取子類設置的顯示或者隱藏的狀態進行操作
#3. 在最外層,也就是TabBarController包裹的子VC里的
#`- (void)viewWillAppear:(BOOL)animated` 
# `- (void)viewWillDisappear:(BOOL)animated`
#這兩個方法里設置顯示或者隱藏
#4. 在點擊TabBar那個監聽方法里,設置自定義TabBar一直顯示,不然會出現切換TabBarController子控制器的也會出現忽閃忽閃的感覺... 

貼代碼大法:

step 1

#import <UIKit/UIKit.h>
#import "WGBTabBar.h"

@interface WGBTabBarViewController : UITabBarController
@property (nonatomic,strong) WGBTabBar *wgbTabBar;
@end

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic,strong) WGBTabBarViewController *tabBarController ;

@end

step 2

- (void)setHiddenTabBar:(BOOL)hiddenTabBar{
    _hiddenTabBar = hiddenTabBar;
    
    AppDelegate  *appDelegate =  (AppDelegate  *)[UIApplication sharedApplication].delegate;
    appDelegate.tabBarController.wgbTabBar.hidden = hiddenTabBar;
}

step 3

在首頁那個層級的VC里如下方法設置:

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.hiddenTabBar = NO;
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    self.hiddenTabBar = YES;
}

step 4

#pragma mark- <WGBTabBarDelegate>
- (void)selectedClickWithIndex:(NSInteger)index{
    self.selectedIndex = index;
    self.wgbTabBar.hidden = NO;
}

以上即是定制一個自定義View的tabBar的基本姿勢.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評論 25 708
  • 前言 很多時候,系統原生的 UITabBar 并不能滿足我們的需求,譬如我們想要給圖標做動態的改變,或者比較炫一點...
    四月_Hsu閱讀 5,092評論 1 6
  • 感恩媽媽沒有對我買了東西啰嗦,還說了我買的東西好吃 感恩老公一路辛苦開車回來 感恩老公對媽媽好好的說話 感恩老公陪...
    貓兒貓兒閱讀 160評論 0 0
  • 一回家就要洗澡 有空要去運動運動運動運動運動運動 早睡早起身體好
    Lucy梁菇涼閱讀 262評論 0 0
  • 午加餐:櫻桃 參考目標: 1份豆2份肉3份“新鮮”水果4份谷物/薯5份蔬菜,深綠色葉菜最好6杯水 今日總結: 食物...
    靜趣_兒童心理師閱讀 357評論 0 0