LoginSignup
3
3

More than 5 years have passed since last update.

Swift3 UIViewControllerをStoryboardから呼び出すいい感じなExtension

Posted at

バージョン

Xcode 8.3.2
Swift 3.1

参考

https://github.com/to4iki/conference-app-2017-ios/blob/f303d2e02e3d6f2c4638049c3389e4d6a13b6286/conference-app-2017/data/extension/UIViewControllerExtension.swift

※参考ってかほぼコピペ

本題

UIViewControllerExtension.swift
protocol StoryBoardInstantiatable {}

extension StoryBoardInstantiatable where Self: UIViewController {

    static func instantiate() -> Self {
        let bundle = Bundle(for: self.self)
        let subName = self.removeViewControllerAtTheEndOf(str: String(describing: self.self))

        guard let vc = UIStoryboard(name: subName, bundle: bundle).instantiateInitialViewController() as? Self else {
            fatalError("エラー:StoryboardからVCの取得に失敗しました。Storyboard Name: \(subName)")
        }

        return vc
    }

    static func instantiateWithIdentifier(_ identifier: String = String(describing: Self.self)) -> Self {
        let bundle = Bundle(for: self.self)
        let subName = self.removeViewControllerAtTheEndOf(str: String(describing: self.self))

        guard let vc = UIStoryboard(name: subName, bundle: bundle).instantiateViewController(withIdentifier: identifier) as? Self else {
            fatalError("エラー:StoryboardからVCの取得に失敗しました。Storyboard Name: \(subName), Identifier: \(identifier)")
        }

        return vc
    }

    static func instantiateEmbedInNavigationController() -> UINavigationController {
        let vc = self.instantiate()
        let nav = UINavigationController(rootViewController: vc)

        return nav
    }

    static func instantiateEmbedInNavigationControllerWithIdentifier(_ identifier: String = String(describing: Self.self)) -> UINavigationController {
        let vc = self.instantiate()
        let nav = BaseNavigationController(rootViewController: vc)

        return nav
    }

    static private func removeViewControllerAtTheEndOf(str: String) -> String {
        return str.replacingOccurrences(of: "ViewController$", with: "", options: .regularExpression, range: nil)
    }
}

extension UIViewController: StoryBoardInstantiatable {}

使い方

SampleViewController クラスの instantiate メソッドから呼び出す Storyboard は Sample.storyboard になります。
ViewController を除いた名前を Storyboard名 にしてください。気に入らない場合は Extension の removeViewControllerAtTheEndOf メソッドを修正してください。

使い方.swift
// MARK: - UIViewController

// Sample.storyboard の isInitial に設定されている ViewController を取得します
let vc = SampleViewController.instantiate()
// Sample.storyboard の Identifier に SampleViewController が設定されている ViewController を取得します
let vc = SampleViewController.instantiateWithIdentifier()
// Sample.storyboard の Identifier に TestViewController が設定されている ViewController を取得します
let vc = SampleViewController.instantiateWithIdentifier("TestViewController")

// MARK: - UINavigationController

// 下記は上記で取得したViewControllerをUINavigationControllerのrootに設定して、NavigationControllerを返すメソッドです
let vc = SampleViewController.instantiateEmbedInNavigationController()
let vc = SampleViewController.instantiateEmbedInNavigationControllerWithIdentifier()
let vc = SampleViewController.instantiateEmbedInNavigationControllerWithIdentifier("TestViewController")

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3