Typhoon using storyboard with view controller initializers

I want to use storyboards to create a view controller named "child", so I define:

- (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 make this a singleton
    }];
}

- (ChildViewController *)childViewControllerFromStoryboard
{
    return [TyphoonDefinition withFactory:self.storyBoard selector:@selector(instantiateInitialViewController)];
}

      

I will have a root view controller which will contain the child view controller

- (RootViewController *)rootViewController {
    return [TyphoonDefinition withClass:[RootViewController class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(initWithChildViewController:) parameters:^(TyphoonMethod *initializer) {
            [initializer injectParameterWith:self.childViewControllerFromStoryboard];
        }];
    }]; 
}

      

The last part is for injecting dependencies for the child view controller:

- (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)]
    }];
}

      

Super normal, I just use its initializer, but it never gets called. I think because it is initWithCoder:

always used, the one that is for storyboarding.

Questions:

  • Can view controller initializers be used with storyboard? It looks like no, like appDelegate.
  • Is this the easiest way to use storyboards directly from an assembly?
  • If I have multiple storyboards, is there a way to define storyboards parametrically? I don't want to end up with something like storyBoard1, storyBoard2, ..., storyBoardN

    .

Thanks in advance.

+3


source to share


2 answers


Thanks for your interest in the typhoon!

  • Can view controller initializers be used with storyboard? It looks like no, like appDelegate.

No, you cannot initialize an object twice (you can call a method twice init

, but it is odd and incorrect and may cause errors).

Every UIViewController and UIView created from Xib / Storyboard uses an initialization method initWithCoder:

.

Instead, you can use method injection and inject setData:

or use property injection.

  1. Is this the easiest way to use storyboards directly from an assembly?

Not. The easiest approach is to use the self-tuning plist. (When the starting name of the storyboard is specified in Info.plist)



Check out the guide here:

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

But if you have another storyboard, you can specify an initial value in the plist and another in the assembly.

  1. If I have multiple storyboards, is there a way to define storyboards parametrically? I don't want to end up with something like storyBoard1, storyBoard2, ..., storyBoardN.

Yes, you can use the runtime arguments typhoon function for that. Using runtime arguments, your definition becomes

- (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]];
        }];
     }];
}

      

Is this what you are asking for?

+5


source


To reduce the code for storyboard definitions, I add a category to TyphoonDefinition

like:

@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 make this a singleton
    }];
}

@end

      



Since it is outside the assembly, it does not register more than once.

+2


source







All Articles