Skip to content

Instantly share code, notes, and snippets.

@DanielCardonaRojas
Created April 13, 2019 14:04
Show Gist options
  • Save DanielCardonaRojas/87847e05efaad71c9a4643d1f6ad4744 to your computer and use it in GitHub Desktop.
Save DanielCardonaRojas/87847e05efaad71c9a4643d1f6ad4744 to your computer and use it in GitHub Desktop.
Helper protocol for easy controller instantiation.
/*
It is encouraged to use the same class name for the controller story board identifier,
but this protocol is flexible to allow defining the story from where to instantiate the
controller as well its identifier.
You can choose to keep the convention while just changing the story board where the controller
is located.
e.g:
extension SettingsViewController {
static var board : String {
return "SomeOtherStoryBoard"
}
}
or implement both.
*/
protocol Storyboarded: class {
static var board: String { get }
static var boardId: String? { get }
static func instantiate() -> Self?
}
//MARK: - Free implementations computed from protocol requirements
extension Storyboarded {
// Assuming the initialViewController of the board is your desired controller
static var storyboard: UIStoryboard {
return UIStoryboard(name: Self.board, bundle: Bundle.main)
}
static func instantiateInitial() -> Self? {
return Self.storyboard.instantiateInitialViewController() as? Self
}
// Unwrapped/Unsafe versions (will fail at runtime)
static func instantiated() -> Self {
return Self.instantiate()!
}
static func instantiated<T: UIViewController>(as subtype: T.Type) -> T {
let className = Self.boardId ?? String(describing: Self.self)
return Self.storyboard.instantiateViewController(withIdentifier: className) as! T
}
static func instantiatedInitial() -> Self {
return Self.instantiateInitial()!
}
}
// MARK: - Default implementation for UIViewController and subclasses
extension Storyboarded where Self: UIViewController {
// Assumes your controller is in Main.storyboard
static var board: String {
return "Main"
}
static var boardId: String? {
return nil
}
// Asumes your storyboard id has the same name as the viewcontroller class
static func instantiate() -> Self? {
let className = Self.boardId ?? String(describing: Self.self)
return Self.storyboard.instantiateViewController(withIdentifier: className) as? Self
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment