视图控制器FooViewController
需要在创建它时进行一些初始化(自身,而不是托管视图 - 在视图加载之前)。
我希望能够以两种方式创建它:
以编程方式,可能带有一些参数:
FooViewController *fooViewController = [[[FooViewController alloc] initWithSomeData:data] autorelease]; [self.navigationController pushViewController:fooViewController animated:YES];
在Interface Builder中。
对于(1)我会写这样的初始化器:
- (id)initWithSomeData:(Data *)data // designated initializer { if (self = [super initWithNibName:@"FooView" bundle:nil]) { self.title = "Foo"; // perform initialization } return self; } - (id)init { return [self initWithSomeData:nilOrSomeDefaultValue]; } // ... other initializers that call the designated initializer
(我对nib名称进行了硬编码,因为控制器总是使用相同的视图配置,因为它使用的视图根本不涉及调用者)
在Interface Builder中创建时,我希望最终结果与使用无参数init
初始化对象的结果相同。
现在,如果我这样做:
- (id)initWithCoder:(NSCoder *)decoder { return [self init]; }
然后会忽略在Interface Builder中的检查器中设置的title
,wantsFullScreenLayout
和nibName
属性,但这没关系。 nibName在init
中是硬编码的,并且title
设置在那里,以防控制器以编程方式实例化。
问题是未设置parentViewController
(默认initWithCoder:
将根据NIB中的对象层次结构设置它。
如何从笔尖获取父对象?然后我会将initWithCoder:
改为:
- (id)initWithCoder:(NSCoder *)decoder { if (self = [self init]) { _parentViewController = [decoder parentObject]; } return self; }
或者我应该使用一些不同的方法来创建可以通过编程方式和IB实例化的控制器?
答案 0 :(得分:0)
不要,不要,不要尝试制作一个可以使用和不使用笔尖的viewcontroller。这将是一场噩梦,因为nibloading使用了一些正常的入口点并提供了新的入口点,并且在操作系统修订版中它将是脆弱的。
你可以做的是让视图控制器始终从笔尖加载,然后给自己一个方便的初始化器来完成笔尖:
- (id) init {
return [[[self class] alloc] initWithNibNamed:@"MyNibName" bundle:nil];
}
然后你可以通过其他nib以正常方式引用它,并在你不想显式处理nib时调用便捷init方法。
答案 1 :(得分:0)
为什么不在viewDidLoad中执行init内容 - 在IB外部创建时,可以在初始化之后但在调用viewDidLoad之前使用其他一些方法或属性设置初始值。