1.首先要了解:任何控制器,都能添加子控制器
     UIViewController里面有一个方法:
    - (void)addChildViewController:(UIViewController *)childController;
     所有的控制器都继承自UIViewController
 
2.UITabBarController内部结构和管理原则
     2.1 内部结构
          UITabBarController内部有两个子控件,一个存放自控制器view的view    一个TabBar条
     2.2 管理原则
          TabBar上有多少个按钮,由UITabBarController自控制器的个数决定
          按钮的内容有对应的子控制器决定
     2.3 怎么切换?
          点击按钮,就找到按钮对应的控制器,记录当前的按钮
          先移除上一个控制器的view,再把当前按钮对应的+控制器的view添加上去
 
3.自定义UITabBarController的步骤
     3.1 搭建界面(1.存放自控制器的view(占位view) 2.UITabBar)
     3.2 添加子控制器,把按钮的内容保存到子控制器
     3.3 遍历子控制器,给UITabBar添加按钮(给按钮绑定tag 以便区分)
     3.4 监听按钮点击,先移除上一个按钮对应的控制器的view,并记录当前的按钮
     3.5 监听按钮点击,把按钮对应的子控制器的View 添加到占位视图里面
 
 @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *containerView;
@property (nonatomic, weak) UIButton *selectedButton;
@property (weak, nonatomic) IBOutlet UIView *tabBar;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // 添加子控制器
UIViewController *vc = [[UIViewController alloc] init];
vc.title = @"全部";
vc.view.backgroundColor = [UIColor orangeColor];
[self addChildViewController:vc]; UIViewController *vc1 = [[UIViewController alloc] init];
vc1.title = @"视频";
vc1.view.backgroundColor = [UIColor brownColor];
[self addChildViewController:vc1]; UIViewController *vc2 = [[UIViewController alloc] init];
vc2.title = @"图片";
vc2.view.backgroundColor = [UIColor greenColor];
[self addChildViewController:vc2]; // 添加按钮
[self setupTitleButton];
}
#pragma mark - 添加按钮
- (void)setupTitleButton
{
NSInteger count = self.childViewControllers.count;
CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
CGFloat btnW = screenW / count;
CGFloat btnH = self.tabBar.bounds.size.height;
CGFloat btnX = ;
CGFloat btnY = ;
for (int i = ; i < count; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = i;
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
UIViewController *vc = self.childViewControllers[i];
[btn setTitle:vc.title forState:UIControlStateNormal];
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
[self.tabBar addSubview:btn]; // 监听按钮点击
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
if (i == ) {
[self btnClick:btn];
}
}
} - (void)btnClick:(UIButton *)button
{
NSInteger i = button.tag;
_selectedButton.selected = NO;
button.selected = YES;
_selectedButton = button;
// 获取子控制器
UIViewController *vc = self.childViewControllers[i];
// 移除之前的控制器View
[self.containerView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
// 添加当前控制器的view
[self.containerView addSubview:vc.view];
}

UITabBarController底层实现的更多相关文章

  1. iOS 底层框架的浅析

    1.简介 IOS是由苹果公司为iPhone.iPod touch和iPad等设备开发的操作系统. 2.知识点 iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设 ...

  2. iOS 自定义UITabBarController的tabBar

               #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDeleg ...

  3. iOS底层框架浅析

    1.简介 IOS是由苹果公司为iPhone.iPod touch和iPad等设备开发的操作系统. 2.知识点 iPhone OS(现在叫iOS)是iPhone, iPod touch 和 iPad 设 ...

  4. 深入浅出Redis-redis底层数据结构(上)

    1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...

  5. Objective-C中block的底层原理

    先出2个考题: 1. 上面打印的是几,captureNum2 出去作用域后是否被销毁?为什么? 同样类型的题目: 问:打印的数字为多少? 有人会回答:mutArray是captureObject方法的 ...

  6. nodejs操作arduino入门(javascript操作底层硬件)

    用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...

  7. 支撑Java NIO 与 NodeJS的底层技术

    支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...

  8. 介绍,介绍我的底层支持库 Net.Sz.CFramework

    Net.Sz.CFramework  是我自己的底层库,是经过验证的底层库. 包含: socket tcp协议,socket http协议线程池,线程模型,任务模型,定时器模型,日志模块脚本模块一些辅 ...

  9. UITabBarController 升级定制

    UITabBarController 定制 特点 用法 1.准备工作: 加入你的相关图片,放入了Assets.xcassets; 导入Categroy文件夹(这个里面的文件,在这里不详细说明了,有疑问 ...

随机推荐

  1. HOSTS文件详解【win|mac】

    hosts文件是一个用于储存计算机网络中各节点信息的计算机文件.这个文件负责将主机名映射到相应的IP地址. hosts文件通常用于补充或取代网络中DNS的功能.和DNS不同的是,计算机的使用者可以直接 ...

  2. 微信自定义菜单说php json_encode不转义中文汉字的方法

    http://blog.csdn.net/qmhball/article/details/45690017 最近在开发微信自定义菜单. 接口比较简单,就是按微信要求的格式post一段json数据过去就 ...

  3. flink - 反压

    http://wuchong.me/blog/2016/04/26/flink-internals-how-to-handle-backpressure/ https://ci.apache.org/ ...

  4. OpenMP初步(英文)

    Beginning OpenMP OpenMP provides a straight-forward interface to write software that can use multipl ...

  5. 毕老师的Editplus

    简介 EditPlus是一款由韩国 Sangil Kim (ES-Computing)出品的小巧但是功能强大的可处理文本.HTML和程序语言的Windows编辑器,你甚至可以通过设置用户工具将其作为C ...

  6. [LeetCode] Decode Ways(DP)

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  7. linux i2c 设备节点读写

    最近需要操作24C02,封装了一下函数方便以后操作. 参考链接: https://my.oschina.net/handawei/blog/68526 http://blog.csdn.net/one ...

  8. 我的工具箱之MyEclipse9.1

    下载地址:http://pan.baidu.com/s/1bbuN1s 这个工具是用来开发Java程序,自带JDK和Tomcat,功能全面周到,使用方便. 市面上MyEclipse版本很多,但都需要破 ...

  9. groovy

    1.加载和卸载(每次都新建一个GroovyClassLoader 实例,然后使用新建的classloader去加载) try { GroovyClassLoader groovyClassLoader ...

  10. 1.Oracle数据库概述

    Oracle数据库概述 1.1Oracle结构图 1.1如何访问数据库 a.本机直接通过sock(套接字)方式访问  IPC UDP协议 ,不需要网络 b.通过tcp建立连接到oracle服务器 1. ...