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的基本姿势.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,376评论 25 707
  • 前言 很多时候,系统原生的 UITabBar 并不能满足我们的需求,譬如我们想要给图标做动态的改变,或者比较炫一点...
    四月_Hsu阅读 4,992评论 1 6
  • 感恩妈妈没有对我买了东西啰嗦,还说了我买的东西好吃 感恩老公一路辛苦开车回来 感恩老公对妈妈好好的说话 感恩老公陪...
    猫儿猫儿阅读 143评论 0 0
  • 一回家就要洗澡 有空要去运动运动运动运动运动运动 早睡早起身体好
    Lucy梁菇凉阅读 260评论 0 0
  • 午加餐:樱桃 参考目标: 1份豆2份肉3份“新鲜”水果4份谷物/薯5份蔬菜,深绿色叶菜最好6杯水 今日总结: 食物...
    静趣_儿童心理师阅读 338评论 0 0