Skip to content

Instantly share code, notes, and snippets.

@rsaenzi
Last active October 19, 2021 13:05
Show Gist options
  • Save rsaenzi/89ded9fff69dd1b9a942c7264dfca375 to your computer and use it in GitHub Desktop.
Save rsaenzi/89ded9fff69dd1b9a942c7264dfca375 to your computer and use it in GitHub Desktop.
To load a UIViewController by the class name, avoiding ! operator and using a string literal for the name of the viewController identifier
//
// UIViewController+Load.swift
//
// Created by Rigoberto Sáenz Imbacuán (https://www.linkedin.com/in/rsaenzi/)
// Copyright © 2019. All rights reserved.
//
import UIKit
extension UIViewController {
/**
This class function works if the UIViewController class name, the Storyboard file name,
and the Storyboard Id of the Scene are the same
*/
static func loadViewController<T: UIViewController>(from bundle: Bundle = .main) -> T {
let identifier = className(some: T.self)
let storyboard = UIStoryboard(name: identifier, bundle: bundle)
guard let screen = storyboard.instantiateViewController(withIdentifier: identifier) as? T else {
fatalError("UIViewController with identifier '\(identifier)' was not found")
}
return screen
}
/**
This method works if the UIViewController class name, the Storyboard file name,
and the Storyboard Id of the Scene are the same
*/
func loadViewController<T: UIViewController>(from bundle: Bundle = .main) -> T {
let identifier = className(some: T.self)
let storyboard = UIStoryboard(name: identifier, bundle: bundle)
guard let screen = storyboard.instantiateViewController(withIdentifier: identifier) as? T else {
fatalError("UIViewController with identifier '\(identifier)' was not found")
}
return screen
}
}
extension UIViewController {
/**
Loads the initial UIViewController in the storyboard. This class function works if the
UIViewController class name, and the Storyboard file name are the same
*/
static func loadFirstViewController(from bundle: Bundle = .main) -> UIViewController {
let identifier = className(some: self)
let storyboard = UIStoryboard(name: identifier, bundle: bundle)
guard let screen = storyboard.instantiateInitialViewController() else {
fatalError("Initial UIViewController with identifier '\(identifier)' was not found")
}
return screen
}
/**
Loads the initial UIViewController in the storyboard. This method works if the
UIViewController class name, and the Storyboard file name are the same
*/
func loadFirstViewController(from bundle: Bundle = .main) -> UIViewController {
let identifier = className(some: self)
let storyboard = UIStoryboard(name: identifier, bundle: bundle)
guard let screen = storyboard.instantiateInitialViewController() else {
fatalError("Initial UIViewController with identifier '\(identifier)' was not found")
}
return screen
}
}
extension UIStoryboard {
static func load<T: UIViewController>() -> T {
let sceneId = className(some: T.self)
let storyboard = UIStoryboard(name: sceneId, bundle: .main)
guard let screen = storyboard.instantiateViewController(withIdentifier: sceneId) as? T else {
fatalError("No UIViewController with ID \(sceneId) was found")
}
return screen
}
}
@rsaenzi
Copy link
Author

rsaenzi commented Mar 12, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment