一:首先查看一下关于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/ green:102.0/ blue:102.0/ alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal]; [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/ green:73.0/ blue:87.0/ 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委托内容

、视图将要切换时调用,viewController为将要显示的控制器,如果返回的值为NO,则无法点击其它分栏了(viewController指代将要显示的控制器)

- (BOOL)tabBarController:(UITabBarController *)tabBarController  shouldSelectViewController:(UIViewController *)viewController
例如1: - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{ NSLog(@"被选中的控制器将要显示的按钮");
//return NO;不能显示选中的控制器
return YES; }
、视图已经切换后调用,viewController 是已经显示的控制器 - (void)tabBarController:(UITabBarController *)tabBarControllerdidSelectViewController:(UIViewController *)viewController
例如2:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
NSLog(@"视图显示后调用");
}
、将要开始自定义item的顺序 - (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers
例如3 - (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers
{ NSLog(@"将要开始自定义item时调用"); NSLog(@"%@",viewControllers);
}
、将要结束自定义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相关属性运用

) 用来控制一组控制器的切换,类似选项卡,每个Tab控制一个试图控制器,点击哪个tab就显示对应的试图控制器,当前的试图控制器

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

最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,每天都会更新一些深度内容,在这里如果你感兴趣也可以关注一下(嘿对美女跟知识感兴趣),当然可以关注后输入:github 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;

你真的了解UITabBarController吗?的更多相关文章

  1. UI第十六节——UITabBarController详解

    一.UITabBarController主要用来管理你提供的content view controllers,而每一个 content view controller则负责管理自己的view层级关系, ...

  2. [BS-30] 你真的会用storyboard开发吗?

    你真的会用storyboard开发吗?   随着苹果大屏手机的推出,苹果公司马上推出了屏幕适配的一些东西Constraints and Size Classes同时,在开发项目时候,是使用sb还是写代 ...

  3. UITabBarController 详解之 hidesBottomBarWhenPushed的正确用法

    今天说的是在TabBar嵌套Nav时,进行Push的时候隐藏TabBar的问题. 之前项目也需要这么做,那时候iOS7还没出,也是各种搜罗,后来的解决方法是当push操作的时候自己隐藏Tabbar,p ...

  4. App你真的需要么

    随着智能手机.移动路联网的普及,APP火的一塌糊涂,APP应用可谓五花八门,街上经常看到各种推广:扫码安装送东西,送优惠券.仿佛一夜之间一个企业没有自己的APP就跟不上时代了. 有时我在想:APP,你 ...

  5. [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?

    你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...

  6. 你真的会玩SQL吗?之逻辑查询处理阶段

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  7. SQL Server中SELECT会真的阻塞SELECT吗?

    在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...

  8. 您真的理解了SQLSERVER的日志链了吗?

    您真的理解了SQLSERVER的日志链了吗? 先感谢宋沄剑给本人指点迷津,还有郭忠辉童鞋今天在QQ群里抛出的问题 这个问题跟宋沄剑讨论了三天,再次感谢宋沄剑 一直以来,SQLSERVER提供了一个非常 ...

  9. 你真的会玩SQL吗?和平大使 内连接、外连接

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

随机推荐

  1. 基于X86平台的PC机通过网络发送一个int(32位)整数的字节顺序

    1.字节顺序 字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端.大端两种字节顺序.小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处:大端字节序是高字节数据存 ...

  2. eclipse导入项目Archive for required library cannot be read or is not a valid ZIP file

    原因 :部分文件毁坏. 解决办法:1. 在eclipse中运行maven clean install 2. 报错,找到报错的文件物理删除,然后重新运行maven clean install  3. 循 ...

  3. ZOJ Problem Set - 1109 Language of FatMouse

    这道题目最让人头疼的就是该题的input怎么结束,因为它要求输入一个空行的时候则一串字符串输入结束,这就不得不让人绕个弯来解决这个问题. (注:本人习惯于使用C中的字符串操作,但是用到map要求使用s ...

  4. 性能测试工具Locust

    An open source load testing tool. 一个开源性能测试工具. define user behaviour with python code, and swarm your ...

  5. 重温JSP学习笔记--El函数库

    EL函数库(由JSTL提供的) * 导入标签库:<%@ tablib prefix="fn" uri="http://java.sun.com/jsp/jstl/f ...

  6. 使用FileSystemWatcher监控文件夹及文件

    引言 这一周主要精力集中学习一个同事开发的本地文件搜索项目上,其中客户端添加共享文件时主要是使用FileSystemWatcher 监控文件,并在各种事件发生时向服务器发送消息. 解决方法 FileS ...

  7. 到处都是坑的微信支付V3之 微信支付回调页面

    据上次 到处都是坑的微信支付V3 后很多园友在被虐了千百遍后终于跳转到了亲切的微信支付界面,但输入密码支付后却不知道怎么处理了,接下来补上支付后的处理流程. 1. html中根据前台支付后反馈信息成功 ...

  8. SQL Server安全(11/11):审核(Auditing)

    在保密你的服务器和数据,防备当前复杂的攻击,SQL Server有你需要的一切.但在你能有效使用这些安全功能前,你需要理解你面对的威胁和一些基本的安全概念.这篇文章提供了基础,因此你可以对SQL Se ...

  9. Xamarin.Android再体验之简单的登录Demo

    一.前言 在空闲之余,学学新东西 二.服务端的代码编写与部署 这里采取的方式是MVC+EF返回Json数据,(本来是想用Nancy来实现的,想想电脑太卡就不开多个虚拟机了,用用IIS部署也好) 主要是 ...

  10. 我的微软MVP申请历程

    10月10日晚更新: 今天看到这篇博客好多朋友点了推荐上了博客园首页最多推荐,很开心,感谢大家的鼓励! 张善友大哥也写过一篇文章: 10年微软MVP路(如何成为一个MVP?) 写的更为详细,大家也可以 ...