Skip to content

Instantly share code, notes, and snippets.

@christianhatch
Last active January 27, 2022 22:27
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save christianhatch/442a2ce232f17e4d7172535bafacd640 to your computer and use it in GitHub Desktop.
Save christianhatch/442a2ce232f17e4d7172535bafacd640 to your computer and use it in GitHub Desktop.
A simple UIStoryboard extension to easily instantiate viewcontrollers using Swift type casting. Raw
// Do you often find yourself writing lines of code that look like this?
// let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as! ViewController
// Here's a simpler way, using generics and Swift type-casting (as long as the viewcontroller's storyboard identifier is its class name).
// Now you can write: let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController() as ViewController
extension UIStoryboard {
func instantiateViewController<T: UIViewController>() -> T {
guard let vc = instantiateViewControllerWithIdentifier(String(T)) as? T else {
fatalError("Could not locate viewcontroller with with identifier \(String(T)) in storyboard.")
}
return vc
}
}
@khaledannajar
Copy link

How to make it work for other classes, not just the initial class?

@hishma
Copy link

hishma commented Jan 27, 2022

My take:

extension UIStoryboard {
    /// Creates a view controller from a supplied type and optional identifier.
    ///
    /// If no identifier is supplied the class name is used. This allows you to just name your view controllers
    /// with their class name.
    /// - Returns: A `UIViewController` instance of the specified type.
    func instantiateViewController<T>(ofType type: T.Type, withIdentifier identifier: String? = nil) -> T {
        let identifier = identifier ?? String(describing: type)
        guard let viewController = instantiateViewController(withIdentifier: identifier) as? T else {
            preconditionFailure("Expected view controller with identifier \(identifier) to be of type \(type)")
        }
        return viewController
    }

    /// Creates an initial view controller of the supplied type.
    /// - Returns: A `UIViewController` instance of the specified type.
    func instantiateInitialViewController<T>(ofType type: T.Type) -> T {
        guard let viewController = instantiateInitialViewController() as? T else {
            preconditionFailure("Expected initial view controller to be of type \(type)")
        }
        return viewController
    }
}

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