我想用故事板创建一个名为“child”的视图控制器,所以我定义了:
- (TyphoonStoryboard *)storyBoard
{
return [TyphoonDefinition withClass:[TyphoonStoryboard class] configuration:^(TyphoonDefinition* definition) {
[definition useInitializer:@selector(storyboardWithName:factory:bundle:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:@"Storyboard"];
[initializer injectParameterWith:self];
[initializer injectParameterWith:[NSBundle mainBundle]];
}];
definition.scope = TyphoonScopeSingleton; //Let's make this a singleton
}];
}
- (ChildViewController *)childViewControllerFromStoryboard
{
return [TyphoonDefinition withFactory:self.storyBoard selector:@selector(instantiateInitialViewController)];
}
我将有一个包含子视图控制器的根视图控制器
- (RootViewController *)rootViewController {
return [TyphoonDefinition withClass:[RootViewController class] configuration:^(TyphoonDefinition *definition) {
[definition useInitializer:@selector(initWithChildViewController:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:self.childViewControllerFromStoryboard];
}];
}];
}
最后一部分只是为子视图控制器注入依赖项:
- (ChildViewController *)childViewController {
return [TyphoonDefinition withClass:[ChildViewController class] configuration:^(TyphoonDefinition *definition) {
// Initilization doesn't work.
[definition useInitializer:@selector(initWithData:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:self.data];
}];
// Property injection does.
// [definition injectProperty:@selector(data)]
}];
}
超级正常,我只是使用它的初始化器,但它永远不会被调用。我认为这是因为总是使用initWithCoder:
,指定用于故事板的那个。
问题:
storyBoard1, storyBoard2, ..., storyBoardN
。提前致谢。
答案 0 :(得分:5)
感谢您对Typhoon的兴趣!
- 可以在故事板中使用视图控制器初始化程序吗?看起来不像,类似于appDelegate。
醇>
不,你不能两次初始化对象(你可以两次调用init
方法,但它奇怪且不正确,可能导致错误)。
从Xib / Storyboard创建的每个UIViewController和UIView都使用initWithCoder:
初始化方法。
相反,您可以使用方法注入并注入setData:
或使用属性注入。
- 这是直接从装配中使用故事板的最简单方法吗?
醇>
没有。最简单的方法是使用plist bootstrapping。 (当在Info.plist中指定初始故事板名称时)
查看指南:
但是如果你有更多的故事板,那么你可以在plist中指定initial,在程序集中指定其他。
- 如果我有几个故事板,有没有一种参数化定义故事板的方法?我不希望最终得到像storyBoard1,storyBoard2,...,storyBoardN这样的东西。
醇>
是的,您可以使用运行时参数台风功能。 使用运行时参数,您的定义变为
- (TyphoonStoryboard *)storyBoardWithName:(NSString *)name
{
return [TyphoonDefinition withClass:[TyphoonStoryboard class] configuration:^(TyphoonDefinition* definition) {
[definition useInitializer:@selector(storyboardWithName:factory:bundle:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:name]; // <-- runtime argument injection
[initializer injectParameterWith:self];
[initializer injectParameterWith:[NSBundle mainBundle]];
}];
}];
}
这是你要求的吗?
答案 1 :(得分:2)
要减少故事板定义的代码,我最终会将类别添加到TyphoonDefinition
,如:
@implementation TyphoonDefinition (Storyboard)
+ (TyphoonStoryboard *)withStoryboardName:(NSString *)storyboardName factory:(TyphoonComponentFactory *)factory
{
return [TyphoonDefinition withClass:[TyphoonStoryboard class] configuration:^(TyphoonDefinition* definition) {
[definition useInitializer:@selector(storyboardWithName:factory:bundle:) parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:storyboardName];
[initializer injectParameterWith:factory];
[initializer injectParameterWith:[NSBundle mainBundle]];
}];
definition.scope = TyphoonScopeSingleton; //Let's make this a singleton
}];
}
@end
因为它在程序集之外,所以它不会多次注册。