iOS - UITabBarController中的坑
当你创建一个继承与UITabBarController的子类 并想给其自定义构造方法 传一些值的时候这时候问题出现了:
在创建的时候里面的init方法回调用了 viewdidload,导致每次传值的时候都会在viewdidload加载完了之后传的值才能传过去
如下代码
- (instancetype)initWithURLStrings:(NSArray *)urls{
self = [super init];//在调用init的时候回调用viewDidLoad 导致参数传入进来时已经加载完了
if (self) {
self.urls = urls;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setUpChild];
self.tabBar.backgroundColor = [UIColor whiteColor];
}
- (void)setUpChild{
// 1.初始化子控制器
KHHomeVC *home = [[KHHomeVC alloc] initWithURL:self.urls[]];
[self addChildVc:home title:@"首页" image:@"tab_home_n" selectedImage:@"tab_home_s"];
KHVipVC *vipVC = [[KHVipVC alloc] initWithURL:self.urls[]];
[self addChildVc:vipVC title:@"会员" image:@"tab_user_n" selectedImage:@"tab_user_s"];
KHMineDetailVC *settingVC = [[KHMineDetailVC alloc] initWithURL:self.urls[]];
[self addChildVc:settingVC title:@"设置" image:@"tab_setting_n" selectedImage:@"tab_setting_s"];
}
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 设置子控制器的文字
childVc.title = title; // 同时设置tabbar和navigationBar的文字
// 设置子控制器的图片
childVc.tabBarItem.image = [UIImage imageNamed:image];
if (iOS7) {
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
} else {
childVc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];
}
// 设置文字的样式
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:];
NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
selectTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed: green:/255.0 blue:/255.0 alpha:];
[childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
[childVc.tabBarItem setTitleTextAttributes:selectTextAttrs forState:UIControlStateSelected];
// 先给外面传进来的小控制器 包装 一个导航控制器
KHNavigationController *nav = [[KHNavigationController alloc] initWithRootViewController:childVc];
nav.navigationBarHidden = YES;
// 添加为子控制器
[self addChildViewController:nav];
}
这是怎么回事的 我们知道在一般控制器中我们想要自定义构造方法 会先走完初始化方法然后再走 viewDidLoad 但是这个UITabBarController怎么这么特殊呢呢?
经过一番查找终于知道了原来这是UITabBarController的一个特性
其实UITabBarController在init的时候,会增UITabbar到self.view,这时候必须加载self.view出来,从而就调用了loadview,进而调用viewdidload、viewwillappear等。这个是UITabBarController的特性
UITabBarController在调用【super init】的时候,系统调用了self.view的东西,但是此时view还没加载出来,于是系统强制先调用viewdidload去加载self.view,最后加载完了,再接着走init方法中的 if(self)条件语句。
解决方案:
就是不要在viewdidload 方法里写加载界面的代码,可以单独再写个方法,直接在init结束的时候调用。所以我的建议就是直接把viewdidload和viewwillappear方法删了,加载界面全都在init里写,如下:
- (instancetype)initWithURLStrings:(NSArray *)urls{
self = [super init];//在调用init的时候回调用viewDidLoad 导致参数传入进来时已经加载完了
if (self) {
self.urls = urls; //初始化数据
[self setUpChild]; //这是解决的重点
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tabBar.backgroundColor = [UIColor whiteColor];
}
- (void)setUpChild{
// 1.初始化子控制器
KHHomeVC *home = [[KHHomeVC alloc] initWithURL:self.urls[]];
[self addChildVc:home title:@"首页" image:@"tab_home_n" selectedImage:@"tab_home_s"];
KHVipVC *vipVC = [[KHVipVC alloc] initWithURL:self.urls[]];
[self addChildVc:vipVC title:@"会员" image:@"tab_user_n" selectedImage:@"tab_user_s"];
KHMineDetailVC *settingVC = [[KHMineDetailVC alloc] initWithURL:self.urls[]];
[self addChildVc:settingVC title:@"设置" image:@"tab_setting_n" selectedImage:@"tab_setting_s"];
}
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 设置子控制器的文字
childVc.title = title; // 同时设置tabbar和navigationBar的文字
// 设置子控制器的图片
childVc.tabBarItem.image = [UIImage imageNamed:image];
if (iOS7) {
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
} else {
childVc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];
}
// 设置文字的样式
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:/255.0 green:/255.0 blue:/255.0 alpha:];
NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
selectTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed: green:/255.0 blue:/255.0 alpha:];
[childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
[childVc.tabBarItem setTitleTextAttributes:selectTextAttrs forState:UIControlStateSelected];
// 先给外面传进来的小控制器 包装 一个导航控制器
KHNavigationController *nav = [[KHNavigationController alloc] initWithRootViewController:childVc];
nav.navigationBarHidden = YES;
// 添加为子控制器
[self addChildViewController:nav];
}
我发现只有继承自UINavigationController和UITabBarController的类的init函数会产生loadView、viewDidLoad函数在初始化[super init]函数调用后就执行,一般UIViewController没有这个问题
@implementation UIViewControllerSubclass
- (id)init {
NSLog(@"");
if (self = [super init]) {
NSLog(@"");
}
return self;
}
- (void)loadView {
[super loadView];
NSLog(@"");
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"");
}
@end
console output
d
iOS - UITabBarController中的坑的更多相关文章
- iconfont在ios(safari)中的坑
最近公司决定将项目图标整体迁移到iconfont,按网上常规方法,在安卓.pc端都没问题,唯独在ios的safari浏览器及微信内置浏览器中,iconfont始终在正常位置向下偏移,导致图标错乱. 网 ...
- iOS中 UITabBarController中自定义UITabBar
1.创建多个视图控制器,放如UITabBarController中 AViewController *aa = [[AViewController alloc] init]; UINavigation ...
- iOS开发中你是否遇到这些经验问题
前言 小伙伴们在开发中难免会遇到问题, 你是如何解决问题的?不妨也分享给大家!如果此文章其中的任何一条问题对大家有帮助,那么它的存在是有意义的! 反正不管怎样遇到问题就要去解决问题, 在解决问题的同时 ...
- iOS开发中静态库制作 之.a静态库制作及使用篇
iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...
- (翻译)开始iOS 7中自动布局教程(二)
这篇教程的前半部分被翻译出来很久了,我也是通过这个教程学会的IOS自动布局.但是后半部分(即本篇)一直未有翻译,正好最近跳坑翻译,就寻来这篇教程,进行翻译.前半部分已经转载至本博客,后半部分即本篇.学 ...
- iOS开发中<null>的处理
在iOS开发过程中经常需要与服务器进行数据通讯,JSON就是一种常用的高效简洁的数据格式. 问题: 在项目中,一直遇到一个坑的问题,程序在获取某些数据之后莫名崩溃.原因是:由于服务器的数据库中有些字段 ...
- GIT在iOS开发中的使用
前言 在iOS开发中,很多公司对项目的版本控制管理都使用了git,当然也有部分公司使用的是svn.当年我最初接触的是svn,觉得使用起来挺方便的,但是每次切分支都需要下载一份新的代码起来,这实在太麻烦 ...
- Unity 发布到IOS,Android的各种坑
Unity 发布到IOS的注意事项1.开发环境MAC环境:Xcode环境 7.2.1Unity环境:Unity5.32.基本说明首先,我说一下,这是我在对Unity发布到IOS的实际使用中,总结出来的 ...
- iOS开发遇到的坑之五--解决工程已存在plist表,数据却不能存入的问题
想写这篇博客其实在一两个月前开发遇见的时候就想把这个问题写成博客的,奈何自己一直懒外加一直没有时间,就把这个事情给耽搁了,好在当时知道下自己一定要把这个问题给描述出来,免得以后其他人遇到这个问题会纠结 ...
随机推荐
- tornado 添加请求头进行允许跨域
什么是跨域? 这个例子是csdn找的, 声明下哈 什么是跨域? 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 所谓同源是指,域名,协议,端口均相同, ...
- resin4.0.23+nginx1.1集群
一,web服务器小论 以前的公司使用的web服务器是tomcat(tomcat+apache作集群),现在的公司是一家互联网公司,采用的架构是resin+nginx作集群(resin比tomcat快? ...
- C语言中的控制语句: 判断、环循等;
列举这一部分的目的就是注意它的写法,尤其是 分号 : 的位置: 1. if-else if else 语句: if (表达式1) 语句1: else if (表达式2) 语句2: else 语句3: ...
- 第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作、增、删、改、查
第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作.增.删.改.查 elasticsearch(搜索引擎)基本的索引 ...
- ASP.NET MVC使用Oauth2.0实现身份验证
随着软件的不断发展,出现了更多的身份验证使用场景,除了典型的服务器与客户端之间的身份验证外还有,如服务与服务之间的(如微服务架构).服务器与多种客户端的(如PC.移动.Web等),甚至还有需要以服务的 ...
- 制作移动端手机网站过程中的SEO优化方法技巧
据国内三大运营商数据来看,中国的手机用户数已达10亿,超过2/5的移动用户每个月都会从手机终端访问网页,如今的移动端手机网站比例肯定有提升,但是对于这些存在的移动版本网站来说,马海祥查看了很大一部分手 ...
- This kernel requires an x86-64 CPU, but only detected an i686 CPU.
为了运行一款软件,我也是拼了.彻底的玩了一次,因为A需要B,我去下载B,结果B又需要C,我去下载C,结果……怎一个艰难了得.最关键的是,目前还没有达到目的!!! 先记录下过程,有时间再来一遍,也许我已 ...
- 5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践
5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践 进入编辑模式 小写i在当前字符前插入 大写I 在光标所在行的行首插入 大写O 在光标上面一行插入编辑 小写o在光标下面一行插入编辑 小 ...
- 设置wetty不需要账号登录便可进行命令行操作
前一篇随笔我们将了Linux怎么安装部署Wetty服务,但是我们看到,在浏览器中输入http://127.0.0.1:3000进行访问的时候,还需要我们输入账号密码进行认证(如下图第一行所示). 但在 ...
- vue二级联动select
<div> <span>所在区域</span> <select name="" v-model="country"&g ...