UITabBarController 详解

一、 UITabBarController的原理


1.1 基本概念

父控制器:通过标签控制器管理多个子控制器,标签控制器就称为父控制器

子控制器:添加到标签控制器里的控制器都做为标签控制器的子控制器

标签栏:也叫选项卡栏,方便用户切换到对应的界面,当往标签控制器里添加子控制器,标签栏就会有序的自动生成对应的标签

标签栏按钮:也叫标签,UITabBarButton,这个类只有apple内部开发人员才能使用

1.2 UITabBarController原理

  1. 当UITabBarController做为Window的根控制器时,程序一启动,UITabBarController就会一次性初始化所有子控制器,但是默认只加载第一个控制器视图,其他视图控制器只初始化,但默认不会加载,只有在需要显示的时候才调用loadView方法加载。特殊情况:在AppDelegate中设置其他的子控制器视图的背景颜色,就会提前加载该控制器视图,但不显示该视图。

  2. 每一个控制器视图只加载一次,就会一直存在内存中,当切换子控制器时直接显示,不显示在屏幕上的子控制器不会被销毁。当遇到内存警告时,会释放掉没有加载的子控制器。

  3. 每个视图控制器都有一个tabBarController属性,通过它可以访问所在的UITabBarController,而且对于UITabBarController的直接子视图,其tabBarController属性相当于它的父视图parentViewController。

  4. 每个视图控制器都有一个tabBarItem属性,通过它控制视图在UITabBarController的tabBar中的显示信息

  5. tabBarItem的image属性必须是png格式(建议大小32*32),并且打开alpha通道否则无法正常显示。

当往UITabBarController添加子控制器,标签栏就会有序的自动生成对应的UITabBarButton对象,有多少个子控制器,标签栏就有多少个UITabBarButton对象, 但是子控制器的数量超过5个的时候,标签栏上的第五个UITabBarButton对象就会显示成”More”类型的按钮

二、UITabBarController的知识点


2.1 关于UITabBarController

  1. UITabBarController没有根控制器的概念。在添加了相同的子控制器,不会增加tabitem的数量。子控器可以是UIViewController、UINavigationController、UITableViewController或者其他的视图控制器

  2. UITabBarButton在UITabBar中的位置是均分的,UITabBar的高度为49,UITabBarButton⾥面显⽰什么内容,由对应子控制器的tabBarItem属性来决定

  3. UITabBarController一般作为应用程序的rootViewController,但是它不能作为UINavigationController的根控制器

  4. UITabBarController默认只支持竖屏,当设备方向放生变化时候,它会查询viewControllers属性中包含的所有ViewController,仅当所有的viewController都支持该方向时,UITabBarController才会发生旋转,否则默认的竖向

2.2 关于UITabBar

2.2.1 简介

UITabBar继承于UIView,方便用户切换到对应的界面,当往标签控制器里添加子控制器,标签栏就会有序的自动生成对应的标签;创建一个标签控制器,就默认创建一个标签栏,标签栏最多显示5个标签

2.2.2 UITabBar常用的属性和方法

// 代理
@property(nonatomic,assign) id<UITabBarDelegate> delegate;
// 设置数据模型,不能给系统默认创建的UITabBar设置items
@property(nonatomic,copy) NSArray *items;
// 设置选中数据模型,不能给系统默认创建的UITabBar设置selectedItem
@property(nonatomic,assign) UITabBarItem *selectedItem;
// iOS7之前,tintColor可以修改背景色
@property(nonatomic,retain) UIColor *tintColor;
// iOS7之后,修改背景色只能用barTintColor
@property(nonatomic,retain) UIColor *barTintColor;
// 设置UITabBar的背景图片
@property(nonatomic,retain) UIImage *backgroundImage
// 设置选中的按钮的背景图片
@property(nonatomic,retain) UIImage *selectionIndicatorImage
// 设置阴影图片,但必须设置backgroundImage属性
@property(nonatomic,retain) UIImage *shadowImage
// 设置数据模型,不能给系统默认创建的UITabBar设置items
- (void)setItems:(NSArray *)items animated:(BOOL)animated;

代理方法:

// 选中时调用
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
// 即将编辑时调用
- (void)tabBar:(UITabBar *)tabBar willBeginCustomizingItems:(NSArray *)items;  
// 编辑时调用                  
- (void)tabBar:(UITabBar *)tabBar didBeginCustomizingItems:(NSArray *)items; 
// 即将结束编辑时调用        
- (void)tabBar:(UITabBar *)tabBar willEndCustomizingItems:(NSArray *)items changed:(BOOL)changed; 
// 结束编辑时调用
- (void)tabBar:(UITabBar *)tabBar didEndCustomizingItems:(NSArray *)items changed:(BOOL)changed;

2.2.3 UITabBarItem

----------  UITabBarItem的常用接口

@interface UITabBarItem : UIBarItem

// 设置选中图片
@property(nonatomic,retain) UIImage *selectedImage;
// 设置角标,一般用于提示用户有新消息
@property(nonatomic,copy) NSString *badgeValue;
// 初始化UITabBarItem对象
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag;
// 初始化UITabBarItem对象
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image selectedImage:(UIImage *)selectedImage;
// 初始化UITabBarItem对象
- (instancetype)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag;

@end

----------  UIBarItem的常用接口

@interface UIBarItem : NSObject

// 是否有效
@property(nonatomic,getter=isEnabled) BOOL enabled;
// 设置标题
@property(nonatomic,copy) NSString *title;
// 设置图片
@property(nonatomic,retain) UIImage *image;
// 设置横向图片
@property(nonatomic,retain) UIImage *landscapeImagePhone; 
// 设置图片边距
@property(nonatomic) UIEdgeInsets imageInsets;
// 设置横向图片边距
@property(nonatomic) UIEdgeInsets landscapeImagePhoneInsets;
// 设置对应的控制器的标签
@property(nonatomic) NSInteger tag;

@end


----------  UITabBarSystemItem的枚举类型

typedef NS_ENUM(NSInteger, UITabBarSystemItem) {
    UITabBarSystemItemMore,
    UITabBarSystemItemFavorites,
    UITabBarSystemItemFeatured,
    UITabBarSystemItemTopRated,
    UITabBarSystemItemRecents,
    UITabBarSystemItemContacts,
    UITabBarSystemItemHistory,
    UITabBarSystemItemBookmarks,
    UITabBarSystemItemSearch,
    UITabBarSystemItemDownloads,
    UITabBarSystemItemMostRecent,
    UITabBarSystemItemMostViewed,
};

2.2.4 覆盖UITabBarController自带的tabBar为自定义的tabBar操作原理

tabBar上的按钮是在viewDidAppear的时候拿到 self.tabBar 再调用addSubViews添加上去的,在viewDidAppear之前把控制器的tabBar换成我们自己的tabBar,就会把tabBar上的按钮添加到自己的tabBar上。但是tabBar控制器的tabBar属性是只读的,不能直接赋值,可以利用运行时机制发送消息

三、应用

-(void)RTSetUpSubVcs{
    TGHomeViewController *HomeVC = [[TGHomeViewController alloc]init];
    HomeVC.view.backgroundColor = [UIColor whiteColor];
    BSENavigationController *HomeNav = [self ChildVC:HomeVC
                                           WithTitle:@"今托管"
                                               image:@"tabbar_search"
                                       selectedImage:@"tabbar_search_sel"];
    
    TGRootChildrenViewController *childrenVC = [TGRootChildrenViewController new];
    BSENavigationController *childrenNav = [self ChildVC:childrenVC
                                               WithTitle:@"小孩"
                                                   image:@"tabBar_children"
                                           selectedImage:@"tabBar_children_sel"];
    
    TGMineViewController *MyVC = [TGMineViewController new];
    BSENavigationController *MyNav = [self ChildVC:MyVC
                                         WithTitle:@"我的"
                                             image:@"tabBar_mine"
                                     selectedImage:@"tabBar_mine_sel"];
    self.tabBar.barTintColor = [UIColor whiteColor];//tabbar 背景色
    self.tabBar.translucent = NO;//tarbar非透明
    
    self.viewControllers = @[HomeNav,childrenNav,MyNav];
}

#pragma mark  - 根TabBarController 添加子视图
-(BSENavigationController *)ChildVC:(UIViewController *)VC WithTitle:(NSString *)title image:(NSString *)imagename selectedImage:(NSString *)selectedImageName
{
    VC.title = title;
    UITabBarItem *barItem = [[UITabBarItem alloc]init];
    barItem.title = title;
    barItem.image = [[UIImage imageNamed:imagename]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    barItem.selectedImage = [[UIImage imageNamed:selectedImageName]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    [barItem setTitleTextAttributes:@{NSForegroundColorAttributeName: HEXCOLOR(0x666666)} forState:UIControlStateNormal];
    // 选中状态下的文字颜色
    [barItem setTitleTextAttributes:@{NSForegroundColorAttributeName: HEXCOLOR(kBlueGrayColor)} forState:UIControlStateSelected];
    BSENavigationController *Nav = [[BSENavigationController alloc]initWithRootViewController:VC];
    Nav.tabBarItem = barItem;
    return Nav;
}

四、遇到的问题


1.之前初始化写错了添加子控制器的方法,设置了子控制的backgroundColor 导致 tabbarcontroller初始化所有子控制进入了didload方法。这样的直接坏处就是多数子控制器在didload里面都有网络请求方法,并且接口都有登录权限设置,如果初始化都直接加载,在用户登录成功后所有控制器又要在登录成功后,重新加载一次网络请求。浪费性能,同时也增加了程序的复杂度。

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

推荐阅读更多精彩内容