3

我想使用故事板创建一个名为“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:总是使用它,它是为故事板指定的。

问题:

  1. 可以将视图控制器初始化程序与情节提要一起使用吗?看起来不像,类似于appDelegate。
  2. 这是直接从程序集中使用情节提要的最简单方法吗?
  3. 如果我有几个故事板,有没有办法以参数方式定义故事板?我不想以storyBoard1, storyBoard2, ..., storyBoardN.

提前致谢。

4

2 回答 2

5

感谢您对台风的关注!

  1. 可以将视图控制器初始化程序与情节提要一起使用吗?看起来不像,类似于appDelegate。

不,您不能两次初始化对象(您可以调用init两次方法,但这很奇怪且不正确,可能会导致错误)。

从 Xib/Storyboard 创建的每个 UIViewController 和 UIView 都使用initWithCoder:初始化方法。

相反,您可以使用方法注入并注入setData:或使用属性注入。

  1. 这是直接从程序集中使用情节提要的最简单方法吗?

不,最简单的方法是使用 plist 引导。(当 Info.plist 中指定初始情节提要名称时)

在此处查看指南:

https://github.com/typhoon-framework/Typhoon/wiki/Obtaining-Built-Components#first-bootstrap-typhoon-using-either

但是,如果您有多个故事板,那么您可以在 plist 中指定初始值,而在程序集中指定其他值。

  1. 如果我有几个故事板,有没有办法以参数方式定义故事板?我不想以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]];
        }];
     }];
}

是你要求的吗?

于 2014-10-31T16:39:46.577 回答
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

因为这是在程序集之外,所以它不会多次注册。

于 2014-10-31T23:17:19.800 回答