UITabBarController 详解

2017-10-18  本文已影响237人  leonardni

一、 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里面都有网络请求方法,并且接口都有登录权限设置,如果初始化都直接加载,在用户登录成功后所有控制器又要在登录成功后,重新加载一次网络请求。浪费性能,同时也增加了程序的复杂度。

上一篇下一篇

猜你喜欢

热点阅读