[英]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.