Instantly share code, notes, and snippets.

Embed
What would you like to do?
Init based Storyboard View Controller Instantiation
final class SampleViewController: StoryboardBackedViewController {
// Unfortunately this must be an IUO var, so that we can set the value after super.init
private var member: Foo!
// Proper dependency injection in a storyboard backed VC!
init(foo: Foo) {
super.init(storyboardIdentifier: "SampleViewControllerIdentifier")
// We have to set the members *after* calling super.init, since it changes the instance of `self`.
self.member = foo
}
}
//
// StoryboardBackedViewController.h
// Fabric
//
// Created by Javier Soto on 9/6/15.
// Copyright © 2015 Fabric. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface StoryboardBackedViewController : UIViewController
// This method returns a different instance of self, so properties on self must be set *after* calling this initializer.
- (instancetype)initWithStoryboardIdentifier:(NSString *)storyboardIdentifier NS_DESIGNATED_INITIALIZER;
#pragma mark - Unavailable
- (instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil NS_UNAVAILABLE;
- (_Nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
//
// StoryboardBackedViewController.m
// Fabric
//
// Created by Javier Soto on 9/6/15.
// Copyright © 2015 Fabric. All rights reserved.
//
#import "StoryboardBackedViewController.h"
@interface UIStoryboard (FABMainStoryboard)
+ (instancetype)fab_mainStoryboard;
@end
@implementation UIStoryboard (FABMainStoryboard)
+ (instancetype)fab_mainStoryboard {
return [self storyboardWithName:@"Main" bundle:nil];
}
@end
// Instantiating controllers from UIStoryboard is a horrible API that breaks that designated initializer chain.
// Implementing this in Obj-C so that we can inherit from this and compose initializers properly.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSAssert(NO, @"Must use -%@", NSStringFromSelector(@selector(initWithStoryboardIdentifier:)));
return nil;
}
- (instancetype)initWithStoryboardIdentifier:(NSString *)storyboardIdentifier {
return [[UIStoryboard fab_mainStoryboard] instantiateViewControllerWithIdentifier:storyboardIdentifier];
}
@end
#pragma clang diagnostic pop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment