zoukankan      html  css  js  c++  java
  • iOS

    当你创建一个继承与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[0]]; [self addChildVc:home title:@"首页" image:@"tab_home_n" selectedImage:@"tab_home_s"]; KHVipVC *vipVC = [[KHVipVC alloc] initWithURL:self.urls[1]]; [self addChildVc:vipVC title:@"会员" image:@"tab_user_n" selectedImage:@"tab_user_s"]; KHMineDetailVC *settingVC = [[KHMineDetailVC alloc] initWithURL:self.urls[2]]; [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:136/255.0 green:136/255.0 blue:136/255.0 alpha:1]; NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary]; selectTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:0 green:183/255.0 blue:283/255.0 alpha:1]; [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[0]];
        [self addChildVc:home title:@"首页" image:@"tab_home_n" selectedImage:@"tab_home_s"];
        
        KHVipVC *vipVC = [[KHVipVC alloc] initWithURL:self.urls[1]];
        [self addChildVc:vipVC title:@"会员" image:@"tab_user_n" selectedImage:@"tab_user_s"];
        
        KHMineDetailVC *settingVC = [[KHMineDetailVC alloc] initWithURL:self.urls[2]];
        [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:136/255.0 green:136/255.0 blue:136/255.0 alpha:1];
        NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
        selectTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:0 green:183/255.0 blue:283/255.0 alpha:1];
        [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(@"0");
        if (self = [super init]) {
            NSLog(@"1");
        }
        return self;
    }
    
    - (void)loadView {
        [super loadView];
        NSLog(@"2");
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"3");
    }
    
    @end

    console output

    0
    2
    3
    1

    d

  • 相关阅读:
    git(常用命令)思维导图...
    有关gitlab的神秘操作.....version&&domain设置...
    Gitlab不小心关闭了sign-in,无法登录web的坑。。。
    聊聊CMSIS-RTOS是什么东东
    c#接口interface学习
    没有内置小鹤双拼的rime输入法就是差劲
    stm32中的型号对比——为什么很少用STM32F2,F3?
    stm32软件编程的框架及注意事项——rtos篇
    modbus-poll和modbus-slave工具的学习使用——modbus协议功能码3的解析(及欧姆龙温控器调试笔记)
    keil中error: #70: incomplete type is not allowed—解决方法
  • 原文地址:https://www.cnblogs.com/junhuawang/p/6285257.html
Copyright © 2011-2022 走看看