はじめに
Main.storyboard を使わずに、
自分で作成した Storyboard から ViewController を生成してルートに設定したい時などで
最初に躓くのが Main.storyboard の削除とその後の設定だと思います。
その辺りの情報が少なかったので、自分がいつもやっていることをまとめます。
環境
Xcode 11.4
Swift5
iOS 13.4
Main.storyboard を削除する
まずは早速 Main.storyboard を削除します。
それに加えて ViewController.swift も使用しないので削除します。
次に新しくルートに設定したい Storyboard と ViewController を作成します。
自分は RootViewController という Storyboard と ViewController を作成しました。
ではこのままの状態でビルドして実行してみます。
すると実行はできますが、こんな感じのエラーがでてクラッシュします。
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'Could not find a storyboard named 'Main' in bundle NSBundle
Main という名前の Storyboard を探しにいったけど、見つからなかったというエラーです。
先ほど Main.storyboard は削除したので、見つからないと言われるのは当然ですね。
このエラーはアプリ実行時に起動する Storyboard が Main.storyboard に設定されているため発生しています。
なので、起動する Storyboard の設定を変更します。
起動する Storyboard の設定を変更する
起動する Storyboard は Xcode の Main Interface と Info.plist の UISceneStoryboardFile という項目で設定されています。
ここを新しく作った RootViewController に設定する方法でもルートを指定することができますが、
アプリ起動時の初期画面を条件に応じて切り替えたい時など、初回起動時に何かしたい場合はその方法では対応できないので、SceneDelegate
でルートを指定するやり方で進めていきます。
SceneDelegate
上でルートを設定する場合は、Main Interface の設定は使用しないので、
デフォルトで設定されている Main を削除して空白にします。
info.plist の UISceneStoryboardFile も使用しないので項目ごと削除してしまいます。
SceneDelegate でルートを指定する
最後に SceneDelegate
でルートになる ViewController を指定します。
Storyboard を使用する場合は ViewController を Storyboard から初期化するようにしてください。
// SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
// UIWindow のインスタンスを作成
window = UIWindow(windowScene: windowScene)
// rootViewController にルートにしたい ViewController を指定
// UIStoryboard の instantiateInitialViewController() を使用して
// Storyboard から ViewController を生成
window?.rootViewController = UIStoryboard(name: "RootViewController", bundle: nil).instantiateInitialViewController()
window?.makeKeyAndVisible()
}
}
これで実行すると指定した ViewController が表示されると思います。