你的位置:首页 > 操作系统

[操作系统]你真的了解UITabBarController吗?


一:首先查看一下关于UITabBarController的定义

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarController : UIViewController <UITabBarDelegate, NSCoding>//设置控制器数组@property(nullable, nonatomic,copy) NSArray<__kindof UIViewController *> *viewControllers;//设置控制器数组 动画- (void)setViewControllers:(NSArray<__kindof UIViewController *> * __nullable)viewControllers animated:(BOOL)animated;//选中的控制器@property(nullable, nonatomic, assign) __kindof UIViewController *selectedViewController; //选中索引值@property(nonatomic) NSUInteger selectedIndex;//当item超过五个时 就会有一个更多@property(nonatomic, readonly) UINavigationController *moreNavigationController; @property(nullable, nonatomic, copy) NSArray<__kindof UIViewController *> *customizableViewControllers; //tab条@property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0); //委托@property(nullable, nonatomic,weak) id<UITabBarControllerDelegate> delegate;@end

UITabBarController和UINavigationController一样是用来管理试图控制器的,与导航控制器不同,tabBarController控制器使用数组管理子试图控制器的,并且子试图之间是平等关系,导航控制器所管理的试图控制器之间是在出桟和入桟的关系;

知识点1:在Application的中编码,平时项目要使用继承一个于UITabBarController的控制器里面

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];  self.window.backgroundColor = [UIColor whiteColor];  //初始化一个tabBar控制器  UITabBarController *tb = [[UITabBarController alloc]init];  //设置UIWindow的rootViewController为UITabBarController  self.window.rootViewController = tb;  //创建相应的子控制器  UIViewController *vc1 = [[UIViewController alloc]init];  vc1.view.backgroundColor = [UIColor greenColor];  vc1.tabBarItem.title = @"首页";  vc1.tabBarItem.image = [[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  UIViewController *vc2 = [[UIViewController alloc]init];  vc2.view.backgroundColor = [UIColor blueColor];  vc2.tabBarItem.title = @"分类";  vc2.tabBarItem.image = [[UIImage imageNamed:@"List_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  vc2.tabBarItem.selectedImage = [[UIImage imageNamed:@"List_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal];  [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/255 green:73.0/255 blue:87.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateSelected];  //把子控制器添加到UITabBarController  //[tb addChildViewController:c1];  //[tb addChildViewController:c2];  //或者  tb.viewControllers = @[vc1,vc2];  [self.window makeKeyAndVisible];  return YES;  }

知识点2:moreNavigationController

UITabBar上最多可以显示5个Tab,当我们往UITabBarController中添加超过的viewController超过5个时候,最后一个一个就会自动变成更多,按照设置的viewControlles的顺序,显示前四个viewController的tabBarItem,后面的tabBarItem将不再显示。当点击more时候将会弹出一个标准的navigationViewController,里面放有其它未显示的的viewController,并且带有一个edit按钮,通过点击该按钮可以进入类似与ipod程序中设置tabBar的编辑界面。编辑界面中默认所有的viewController都是可以编辑的,我们可以通过设置UITabBarController的customizableViewControllers属性来指定viewControllers的一个子集,即只允许一部分viewController是可以放到tabBar中显示的。但是这块儿要注意一个问题就是每当UITabBarController的viewControllers属性发生变化的时候,customizableViewControllers就会自动设置成跟viewControllers一致,即默认的所有的viewController都是可以编辑的,如果我们要始终限制只是某一部分可编辑的话,记得在每次viewControlles发生改变的时候,重新设置一次customizableViewControllers。

二:UITabBarControllerDelegate委托内容

1、视图将要切换时调用,viewController为将要显示的控制器,如果返回的值为NO,则无法点击其它分栏了(viewController指代将要显示的控制器)- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController 例如1:- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{  NSLog(@"被选中的控制器将要显示的按钮");  //return NO;不能显示选中的控制器  return YES;} 2、视图已经切换后调用,viewController 是已经显示的控制器- (void)tabBarController:(UITabBarController *)tabBarControllerdidSelectViewController:(UIViewController *)viewController 例如2: - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ NSLog(@"视图显示后调用");} 3、将要开始自定义item的顺序- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers  例如3- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers{   NSLog(@"将要开始自定义item时调用");   NSLog(@"%@",viewControllers);} 4、将要结束自定义item的顺序- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed 例如4 - (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed{    NSLog(@"将要结束自定义item时调用");    NSLog(@"%@",viewControllers);}

5、结束自定义item的顺序

- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed 

  例如5:

 - (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers changed:(BOOL)changed

{

    NSLog(@"已经结束自定义item顺序时调用");

    NSLog(@"%@",viewControllers);

}


三:UIViewController (UITabBarControllerItem)分类

@interface UIViewController (UITabBarControllerItem)//当前视图的UITabBarItem对象@property(null_resettable, nonatomic, strong) UITabBarItem *tabBarItem; //如果视图控制器是一个标签栏控制器的子控制器,则返回它。否则返回nil@property(nullable, nonatomic, readonly, strong) UITabBarController *tabBarController;@end

四:关于UITabBar的定义

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBar : UIView//委托@property(nullable,nonatomic,assign) id<UITabBarDelegate> delegate;   //UITabBarItem集合@property(nullable,nonatomic,copy) NSArray<UITabBarItem *> *items;   //被选中的item@property(nullable,nonatomic,assign) UITabBarItem *selectedItem; //批量设置items- (void)setItems:(nullable NSArray<UITabBarItem *> *)items animated:(BOOL)animated; - (void)beginCustomizingItems:(NSArray<UITabBarItem *> *)items;  - (BOOL)endCustomizingAnimated:(BOOL)animated;  - (BOOL)isCustomizing;//渲染色@property(null_resettable, nonatomic,strong) UIColor *tintColor NS_AVAILABLE_IOS(5_0);//背景色@property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR; //被选中的图片选染色@property(nullable,nonatomic,strong) UIColor *selectedImageTintColor NS_DEPRECATED_IOS(5_0,8_0,"Use tintColor") UI_APPEARANCE_SELECTOR;//背景图@property(nullable, nonatomic,strong) UIImage *backgroundImage NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;//选中指示图@property(nullable, nonatomic,strong) UIImage *selectionIndicatorImage NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR; //阴影图@property(nullable, nonatomic,strong) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;@property(nonatomic) UITabBarItemPositioning itemPositioning NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;//元素宽度@property(nonatomic) CGFloat itemWidth NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;//item间隔@property(nonatomic) CGFloat itemSpacing NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;//风格@property(nonatomic) UIBarStyle barStyle NS_AVAILABLE_IOS(7_0) UI_APPEARANCE_SELECTOR;//是否透明@property(nonatomic,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(7_0);@end

UITabBar包含多个UITabBarItem,每⼀个UITabBarItem对应⼀个UIViewController。UITabBar的⾼度是49;系统最多只显⽰5个UITabBarItem,当UITabBarItem超过5个时系统会⾃动增加⼀个更多按钮,点击更多按钮没有在底部出现的按钮会以列表的形式显⽰出来.

五:UITabBarDelegate内容

@protocol UITabBarDelegate<NSObject>@optional- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item; // called when a new view is selected by the user (but not programatically)- (void)tabBar:(UITabBar *)tabBar willBeginCustomizingItems:(NSArray<UITabBarItem *> *)items;         - (void)tabBar:(UITabBar *)tabBar didBeginCustomizingItems:(NSArray<UITabBarItem *> *)items;           - (void)tabBar:(UITabBar *)tabBar willEndCustomizingItems:(NSArray<UITabBarItem *> *)items changed:(BOOL)changed; - (void)tabBar:(UITabBar *)tabBar didEndCustomizingItems:(NSArray<UITabBarItem *> *)items changed:(BOOL)changed; @end

对于点击哪个UITabBarItem响应事件则是在这个委托里面进行;由于UITabBarController已经遵守了UITabBarDelegate协议,如果有继承UITabBarController已经可以直接运用UITabBarDelegate里面的内容;

知识点1:iOS 点击UITabBar触发刷新

平常我们在切换UITabBarController底部菜单时,它是不会有刷新的功能;如果要实现刷新的效果可以如下实现;原理如下,在监听UITabBar点击的方法中判断本次点击的UITabBarItem和上次点击的是否一样,如果一样就发出通知,首先需要自定义一个UITabBarController (比如LLTabBarController);要判断本次点击的UITabBarItem和上次点击的是否一样,就需要定义一个属性记录下来上次点击的UITabBarItem,并在viewWillAppear:方法中给该属性赋值默认的UITabBarItem

/** 之前被选中的UITabBarItem */@property (nonatomic, strong) UITabBarItem *lastItem;- (void)viewWillAppear:(BOOL)animated{  [super viewWillAppear:animated];  // 将默认被选中的tabBarItem保存为属性  self.lastItem = self.tabBar.selectedItem;}- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item{  // 判断本次点击的UITabBarItem是否和上次的一样  if (item == self.lastItem) { // 一样就发出通知    [[NSNotificationCenter defaultCenter] postNotificationName:@"LLTabBarDidClickNotification" object:nil userInfo:nil];  }  // 将这次点击的UITabBarItem赋值给属性  self.lastItem = item;}

在需要实现点击UITabBar触发刷新功能的控制器中监听通知

- (void)viewDidLoad {  [super viewDidLoad];  // 监听UITabBarItem被重复点击时的通知  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tabBarDidClick) name:@"LLTabBarDidClickNotification" object:nil];}- (void)tabBarDidClick{  // 如果本控制器的view显示在最前面,就下拉刷新  if ([self.view isShowingOnKeyWindow]) { // 判断一个view是否显示在根窗口上,该方法在UIView的分类中实现    [self.tableView.header beginRefreshing]; // MJRefresh  }}

判断一个view是否显示在根窗口上

/** 该方法在UIView的分类中实现 */- (BOOL)isShowingOnKeyWindow{  UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;  // 把这个view在它的父控件中的frame(即默认的frame)转换成在window的frame  CGRect convertFrame = [self.superview convertRect:self.frame toView: keyWindow];  CGRect windowBounds = keyWindow.bounds;  // 判断这个控件是否在主窗口上(即该控件和keyWindow有没有交叉)  BOOL isOnWindow = CGRectIntersectsRect(convertFrame, windowBounds);  // 再判断这个控件是否真正显示在窗口范围内(是否在窗口上,是否为隐藏,是否透明)  BOOL isShowingOnWindow = (self.window == keyWindow) && !self.isHidden && (self.alpha > 0.01) && isOnWindow;  return isShowingOnWindow;}

在控制器销毁时要移除通知

- (void)dealloc{  // 移除通知  [[NSNotificationCenter defaultCenter] removeObserver:self];}

六:UITabBarItem的定义

NS_CLASS_AVAILABLE_IOS(2_0) @interface UITabBarItem : UIBarItem - (instancetype)init NS_DESIGNATED_INITIALIZER;//初始化几中方式- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;- (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image tag:(NSInteger)tag;//初始化 标是 图标 选中图标- (instancetype)initWithTitle:(nullable NSString *)title image:(nullable UIImage *)image selectedImage:(nullable UIImage *)selectedImage NS_AVAILABLE_IOS(7_0);- (instancetype)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag;//给当前的分栏控制器的item设置一个选中状态的图片@property(nullable, nonatomic,strong) UIImage *selectedImage NS_AVAILABLE_IOS(7_0);//角标@property(nullable, nonatomic, copy) NSString *badgeValue;  //IOS7以后过期- (void)setFinishedSelectedImage:(nullable UIImage *)selectedImage withFinishedUnselectedImage:(nullable UIImage *)unselectedImage NS_DEPRECATED_IOS(5_0,7_0,"Use initWithTitle:image:selectedImage: or the image and selectedImage properties along with UIImageRenderingModeAlwaysOriginal");//IOS7以后过期- (nullable UIImage *)finishedSelectedImage NS_DEPRECATED_IOS(5_0,7_0);//IOS7以后过期- (nullable UIImage *)finishedUnselectedImage NS_DEPRECATED_IOS(5_0,7_0);//文字的偏移@property (nonatomic, readwrite, assign) UIOffset titlePositionAdjustment NS_AVAILABLE_IOS(5_0) UI_APPEARANCE_SELECTOR;@end

知识点1:tabBarItem相关属性运用

1) 用来控制一组控制器的切换,类似选项卡,每个Tab控制一个试图控制器,点击哪个tab就显示对应的试图控制器,当前的试图控制器 2) 每个tabBarItem都可以设置title、image/selectedImages、badgeValue 例如:  (1).给当前的分栏控制器的item设置一个标题     self.tabBarItem.title = @"我的";  (2).给当前的分栏控制器的item设置一个图片     self.tabBarItem.image = [UIImage imageNamed:@"tab_buddy_nor@2x"];  (3).给当前的分栏控制器的item设置一个选中状态的图片     self.tabBarItem.selectedImage = [UIImage imageNamed:@"tab_me_nor@2x"];//@2x表示给高清屏 30*30的效果好     self.tabBarItem.badgeValue = @"new";//在小图标的上面家字体加字体 3) 设置选中的颜色   分栏控制器.tabBar.tintColor   self.tabBarController.tabBar.tintColor = [UIColor redColor];  3) TabBar只能显示五个tab Item,如果超过五个则会自动生成个Morede 标签显示剩余的Tab,这些Tab可以通过编辑显示在UITabBar上(打开页面后自动显示在界面,点击tabBar右边) 4) 自定义Item   [UITabBarItem alloc]initWithTitle: image: tag:   [UITabBarItem alloc]initWithTabBarSystemItem:tag: