スタック・オーバーフロー Asked on November 22, 2021
Swiftで起動時に表示されるStoryboardを変更したいと思っています。
普通は、Main.storyboardが起動すると思いますが、私はTestViewController.storyboad」を最初に起動するstoryboardに設定したいです。
今までに試したことは、info.plistでMain storyboard file base nameを「TestViewController」に設定しました。
また、GeneralのDevelopment InfoでMain Interfaceの項目が「TestViewController」に設定されていることを確認しました。
この状態だけでビルドして実行のボタンを押すと、まだMain.storyboardが起動したので、Main.storyboardをプロジェクトから削除しました。
そして、AppDelegate.swiftと、SceneDelegate.swiftを以下のように設定しました。
AppDelegate.swift
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "TestApp")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error (error), (error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error (nserror), (nserror.userInfo)")
}
}
}
}
SceneDelegate.swift
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
let storyboard = UIStoryboard(name: "TestViewController", bundle: nil)
window?.rootViewController = storyboard.instantiateInitialViewController()
window?.makeKeyAndVisible()
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
// Save changes in the application's managed object context when the application transitions to the background.
(UIApplication.shared.delegate as? AppDelegate)?.saveContext()
}
}
-エラー内容-
この状態でビルドして実行すると、以下のようなエラーが出ました。
AppDelegate.swift上で表示されているエラーは以下の通りです。
Thread 1: Exception: "Could not find a storyboard named 'Main' in bundle NSBundle </private/var/containers/Bundle/Application/B8C5DF50-5623-4DCF-A104-5F3CB2E82D61/FACEMOTION3D.app> (loaded)"
コンソール上に表示されているエラーは以下の通りです。
2020-07-22 17:29:57.766217+0900 TestApp[10270:1339085] Metal GPU Frame Capture Enabled
2020-07-22 17:29:57.766370+0900 TestApp[10270:1339085] Metal API Validation Enabled
2020-07-22 17:29:58.144840+0900 TestApp[10270:1339085] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle </private/var/containers/Bundle/Application/B8C5DF50-5623-4DCF-A104-5F3CB2E82D61/TestApp.app> (loaded)'
*** First throw call stack:
(0x1b3228300 0x1b2f3cc1c 0x1b74de028 0x1b6a04260 0x1b6a03b58 0x1b6a05654 0x1b736cd1c 0x1b736d320 0x1b6eefe08 0x1b848affc 0x1b84b15a0 0x1b8495ebc 0x1b84b1234 0x1038d318c 0x1038d6964 0x1b84d76c4 0x1b84d7370 0x1b84d78dc 0x1b31a3af4 0x1b31a3a48 0x1b31a31fc 0x1b319df38 0x1b319d8f4 0x1bd5b4604 0x1b7371358 0x103037184 0x1b30192dc)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
どうしたらエラーが消せますでしょうか?
私もSceneDelegate
が導入されてから、storyboardの付け替えなんかはやったことがなかったので試してみました。確かに、ご質問に記載されただけの修正(*)では、書かれている通りの実行時エラーが発生するようです。(Xcode 11.6で確認。)
(*)AppDelegate.swift と SceneDelegate.swift の修正については、必要とは思えなかったので、まずはプロジェクトテンプレートから出力されたソースを修正せずに試してみました。
プロジェクトの中のどこかにMain.storyboard
を参照している箇所があるわけです。Xcodeの画面左側のナビゲータ領域の検索機能を使うと、設定ファイルの中身まで検索してくれます。
検索バーにMain
と入力すると、Info.plistの中にまだMain
と記載されている部分があるようです。
ここで検索結果のMain
の行をクリックするとその設定部分が開いた状態でInfo.plistが表示されます。
Info.plist中のMain
をTestViewController
に修正します。
後は保存実行すると、先ほどの実行時エラーは出なくなりました。
コードをいじっていないので、何か違う結果が出るかもしれませんが、お試しください。
Answered by OOPer on November 22, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP