Тайфун с использованием раскадровки с инициализаторами контроллера вида
Я хочу использовать раскадровки для создания контроллера представления с именем "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:
всегда используется, тот, который предназначен для раскадровки.
Вопросы:
- Можно ли использовать инициализаторы контроллера представления с раскадровками? Похоже, нет, похоже на appDelegate.
- Это самый простой способ использовать раскадровки прямо из сборки?
- Если у меня есть несколько раскадровок, есть ли способ определить раскадровки параметрически? Я не хочу закончить с чем-то вроде
storyBoard1, storyBoard2, ..., storyBoardN
,
Заранее спасибо.
2 ответа
Спасибо за ваш интерес к Тайфуну!
- Можно ли использовать инициализаторы контроллера представления с раскадровками? Похоже, нет, похоже на appDelegate.
Нет, вы не можете инициировать объект дважды (вы можете вызвать init
метод дважды, но он странный и неправильный и может быть причиной ошибок).
Каждый UIViewController и UIView, созданные из Xib/Storyboard, используют initWithCoder:
метод инициализации.
Вместо этого вы можете использовать метод инъекций и инъекций setData:
или использовать свойство инъекции.
- Это самый простой способ использовать раскадровки прямо из сборки?
Нет. Самый простой подход - это использование plst начальной загрузки. (Когда начальное имя раскадровки указано в Info.plist)
Проверьте руководство здесь:
https://github.com/typhoon-framework/Typhoon/wiki/Obtaining-Built-Components
Но если у вас есть более одной раскадровки, вы можете указать начальный в листе, а другой в сборке.
- Если у меня есть несколько раскадровок, есть ли способ определить раскадровки параметрически? Я не хочу в конечном итоге что-то вроде 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]];
}];
}];
}
Это то, что вы просите?
Чтобы уменьшить код для определений раскадровки, я добавляю категорию к 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
Поскольку это вне сборки, оно регистрируется не более одного раза.