简体   繁体   English

UITabBarController子类从不调用setViewControllers:或setViewControllers:animated:

[英]UITabBarController subclass never calls setViewControllers: or setViewControllers:animated:

I have a simple question: My custom UITabBarController subclass overrides both setViewControllers: and setViewControllers:animated: . 我有一个简单的问题:我的自定义UITabBarController子类覆盖了setViewControllers:setViewControllers:animated: When using my subclass in a storyboard, neither method is called. 在情节提要中使用我的子类时,不会调用任何方法。 Why? 为什么? How is the viewControllers property being set? 如何设置viewControllers属性? Can I somehow hook into the moment when they are being set? 我能以某种方式挂接到设置它们的那一刻吗?

My code: 我的代码:

MyTabBarController.h MyTabBarController.h

#import <UIKit/UIKit.h>

@interface MyTabBarController : UITabBarController <UITabBarControllerDelegate>
@end

MyTabBarController.m MyTabBarController.m

#import "MyTabBarController.m"

@implementation MyTabBarController
- (void)viewDidLoad
{
    NSLog(@"I do get called, and at this point I have viewControllers");
}

- (void)setViewControllers:(NSArray *)viewControllers
{
    NSLog(@"in setViewControllers:");
    [super setViewControllers:viewControllers];
}

- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
{
    NSLog(@"in setViewControllers:animated:");
    [super setViewControllers:viewControllers animated:animated];
}
@end

Note: I know that my subclass is being used because viewDidLoad gets called. 注意:我知道正在使用我的子类,因为调用了viewDidLoad

I agree with @Duncan, that the controllers are set by initWithCoder (or rather loadView ). 我同意@Duncan的观点,控制器是由initWithCoder设置的(或者是loadView )。

Based on that assumption it's kind of obvious why the accessors aren't used: a subclass could override them (and maybe forget the call to super or assume the instance is fully initialized). 基于该假设,很明显为什么不使用访问器:子类可以覆盖它们(并且可能忘记了对super的调用或假定实例已完全初始化)。

Although Apple missed to give advice you can find the recommendation of avoiding accessors during init in Google's Obj-C Styleguide (and I believe I read that Stanford courses recommend that, too). 尽管Apple错过了提供建议的建议,但您可以在Google的Obj-C样式指南中找到避免在init过程中使用访问器的建议(我相信我读过斯坦福大学的课程也建议这样做)。 And I heavily doubt that Apple would have written code to emit KVO-events in the initialisation phase. 而且我非常怀疑苹果是否会编写代码以在初始化阶段发出KVO事件。

So unless you need to manipulate the ViewControllers before they are added, why not go with the straight-forward solution? 因此,除非您需要在添加ViewController之前对其进行操作,否则为什么不采用直接解决方案呢?

- (id)initWithCoder:(NSCoder*)aDecoder 
{
    if(self = [super initWithCoder:aDecoder]) 
    {
        [whateverYouWantToDoWithTheControllers:self.viewControllers];
    }
    return self;
}

- (void)setViewControllers:(NSArray *)viewControllers
{
    [super setViewControllers:viewControllers];
    [whateverYouWantToDoWithTheControllers:viewControllers];
}

- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
{
    [super setViewControllers:viewControllers animated:animated];
    [whateverYouWantToDoWithTheControllers:viewControllers];
}

From the docs it looks to me like setViewControllers:animated is a method intended for 3rd party developers to switch the list of view controllers installed in aa tab bar controller. 从文档看来,setViewControllers:animated是供第三方开发人员用来切换安装在标签栏控制器中的视图控制器列表的方法。

My guess is that when a view controller is loaded from an XIB or a storyboard, it sets itself up using initWithCoder rather than using the public interfaces. 我的猜测是,当从XIB或情节提要中加载视图控制器时,它是使用initWithCoder而不是使用公共接口来设置自身的。 It is likely manipulating the instance variable that holds the array of view controllers manually. 可能会手动操作实例变量来手动保存视图控制器数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM