That's right you just override loadView, rather than looking up the view from the container, as you've shown, you should provide the view via an initializer or property setter. And then in loadView, set it to the injected view as follows:
- (void)loadView
{
[self.view = _myInjectedView]; //Do this rather than looking it up via the TyphoonFactory - easier to test.
}
If you do it this way:
- You can refer to the view via it's actual type, rather than down-casting from UIView
- It'll be really simple to mock-out in a pure unit test. (No need for TyphoonPatcher, swizzling, etc).
Here's an example:
- (id)userDetailsController
{
return [TyphoonDefinition withClass:[UserDetailsController class] initialization:^(TyphoonInitializer* initializer)
{
initializer.selector = @selector(initWithSession:userDetailsView:);
[initializer injectWithDefinition:[self session]];
[initializer injectWithDefinition:[self userDetailsView]];
}];
}
- (id)userDetailsView
{
return [TyphoonDefinition withClass:[UserDetailsView class]
properties:^(TyphoonDefinition* definition)
{
//circular dependency. Can also be set within VC.
[definition injectProperty:@selector(delegate)
withDefinition:[self userDetailsController]];
[definition injectProperty:@selector(sideMargin)
withValueAsText:@"${view.field.default.side.margin}"];
}];
}
Injecting From a Xib
We don't actually have a Xib factory we can provide you yet. It should be a quick job to define one using a similar pattern to the object that emits a theme here, so you'll have a component in the DI container for each of your Xib-based views, and just inject that directly.
Alternatively you could use our new TyphoonFactoryProvider.
If you get stuck, please let us know and one of us will find some time to create and push that Xib-view-factory for you.