🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

10912閲覧

storyboardが使われない設定にしているはずなのにcould not find storyboard named "Main"が出てエラーになる。

lady-navigation

総合スコア11

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

2クリップ

投稿2019/10/01 15:33

編集2019/10/03 02:19

storyboardを使わない設定と、SceneDelegate導入への対応について

storyboardを使わずに、NavigationControllerとTableViewを使って、シンプルな画面遷移を構築したい。

発生している問題・エラーメッセージ

Main.storyboardをゴミ箱に送り、infoからもMainを消したが、"could not find storyboard"のエラーメッセージがでる。また、SceneDelegateの導入により、AppDelegateに書いた処理が実行されない(?)とのことなのでqiitaを参考にコードを追加したが、エラーが直らなかった。

エラーメッセージ Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle ### 該当のソースコード //SceneDelegate.swift import UIKit @available(iOS 13.0, *) 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 } let myFirstViewController: ViewController = ViewController() let nc = UINavigationController(rootViewController: myFirstViewController) let window = UIWindow(windowScene: scene as! UIWindowScene) self.window = UIWindow(frame:UIScreen.main.bounds) self.window = window self.window?.rootViewController = nc window.makeKeyAndVisible() } //遷移前の画面(ViewController.swift) import UIKit class ViewController: UIViewController { let mySections = ["",""] let Settings = [["一般","コントロールセンター","画面表示","壁紙","siri","touch ID"], ["ITunes","Wallet","パスワード"] ] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. var tableView: UITableView = UITableView() tableView = UITableView(frame:CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height),style: .grouped) tableView.delegate = self tableView.dataSource = self self.view.addSubview(tableView) } } extension ViewController: UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return Settings[section].count } func numberOfSections(in tableView: UITableView) -> Int { return mySections.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return mySections[section] } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell: UITableViewCell = UITableViewCell(style: .default, reuseIdentifier: "cell") cell.textLabel!.text = Settings[indexPath.section][indexPath.row] return cell } } extension ViewController: UITableViewDelegate{ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("(indexPath.section+1)番目のセクション、(indexPath.row+1)番目の行が選択されました。") tableView.deselectRow(at: indexPath, animated: true) switch indexPath.section { case 0: switch indexPath.row { case 0: let secondViewController = generalViewController() self.navigationController?.pushViewController(secondViewController, animated: true) break default: break } default: break } } } //遷移先画面(genaralViewController.swift) import Foundation import UIKit let mySections2 = ["","",""] let General = [["情報","ソフトウェア・アップデート"], ["AirDrop","Handoff","Carplay"], ["ホームボタン"] ] class generalViewController: UIViewController { var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() tableView = UITableView(frame: CGRect(x: 0,y: 0,width: self.view.bounds.width, height: self.view.bounds.height),style: .grouped) tableView.dataSource = self self.view.addSubview(tableView) } } extension generalViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return General[section].count } func numberOfSections(in tableView: UITableView) -> Int { return mySections2.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return mySections2[section] } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell: UITableViewCell = UITableViewCell(style: .default, reuseIdentifier: "cell") cell.textLabel?.text = General[indexPath.section ][indexPath.row] return cell } } // AppDelegate.swift import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. if #available(iOS 13, *){ }else{ let myFirstViewController: ViewController = ViewController() let vc = UINavigationController(rootViewController: myFirstViewController) self.window = UIWindow(frame:UIScreen.main.bounds) self.window?.rootViewController = vc self.window?.makeKeyAndVisible() } return true } // MARK: UISceneSession Lifecycle @available(iOS 13.0, *) 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. } } ```ここに言語名を入力 swift ### 試したこと https://qiita.com/omochimetaru/items/31df103ef98a9d84ae6b ・こちらの「以前のiOSのサポート」の部分 ・infoのMain消し ・Main.storyboardをMove to trush ### 補足情報(FW/ツールのバージョンなど) simulatorはIphone 11 Pro Max

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Xcodeの設定のGeneralの項目のMain Interfaceを確認してみてください。

Mainになっていませんか?

イメージ説明

追記(2019/10/03)

Xcode11でiOS13のターゲットのプロジェクトを作成した場合はSceneDelegateAppDelegateはそのままで問題ないと思います。
参考にさせていただいたサイトをみたところ

「ライフサイクルイベント」が発生したときは SceneDelegate か AppDelegate のどちらかのメソッドしか呼ばれない

iOS 13 かつ SceneDelegate が使用されている場合は SceneDelegate が
それ以外では AppDelegate が

となっていたので、
ちょっと自信がありませんが、上記の対応が必要になるのはXcode11でiOS12.x以下をターゲットとしたプロジェクトを作成した時だと思います。

手元で以下のようなコードで生成したViewControllerをルートにして実行することができたので、
参考として貼っておきます。

Swift

1// CodeViewController 2import UIKit 3 4final class CodeViewController: UIViewController { 5 6 // MARK: - UI 7 8 lazy var titleLabel: UILabel = { 9 let label = UILabel() 10 label.translatesAutoresizingMaskIntoConstraints = false 11 label.font = UIFont.boldSystemFont(ofSize: 18) 12 label.text = "Title" 13 return label 14 }() 15 16 lazy var descLabel: UILabel = { 17 let label = UILabel() 18 label.translatesAutoresizingMaskIntoConstraints = false 19 label.font = UIFont.systemFont(ofSize: 15) 20 label.textColor = UIColor.lightGray 21 label.text = "Desc" 22 return label 23 }() 24 25 lazy var button: UIButton = { 26 let button = UIButton() 27 button.translatesAutoresizingMaskIntoConstraints = false 28 button.setTitle("Button", for: .normal) 29 button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 15) 30 button.titleLabel?.textColor = UIColor.white 31 button.backgroundColor = UIColor.blue 32 button.layer.cornerRadius = 4.0 33 return button 34 }() 35 36 // MARK: - Lifecycle 37 38 override func viewDidLoad() { 39 super.viewDidLoad() 40 41 // UI 42 view.backgroundColor = .white 43 view.addSubview(titleLabel) 44 view.addSubview(descLabel) 45 view.addSubview(button) 46 setupLayout() 47 } 48} 49 50// MARK: - AutoLayout 51extension CodeViewController { 52 53 func setupLayout() { 54 // titleLabel 55 NSLayoutConstraint.activate([ 56 titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0), 57 titleLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0) 58 ]) 59 60 // descLabel 61 NSLayoutConstraint.activate([ 62 descLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8), 63 descLabel.centerXAnchor.constraint(equalTo: titleLabel.centerXAnchor, constant: 0) 64 ]) 65 66 // button 67 NSLayoutConstraint.activate([ 68 button.topAnchor.constraint(equalTo: descLabel.bottomAnchor, constant: 16), 69 button.centerXAnchor.constraint(equalTo: descLabel.centerXAnchor, constant: 0), 70 button.widthAnchor.constraint(equalToConstant: 88), 71 button.heightAnchor.constraint(equalToConstant: 44) 72 ]) 73 } 74} 75

AppDelegateはプロジェクト生成時のままです。

Swift

1// AppDelegate 2import UIKit 3 4@UIApplicationMain 5class AppDelegate: UIResponder, UIApplicationDelegate { 6 7 8 9 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 10 // Override point for customization after application launch. 11 return true 12 } 13 14 // MARK: UISceneSession Lifecycle 15 16 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 17 // Called when a new scene session is being created. 18 // Use this method to select a configuration to create the new scene with. 19 return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 20 } 21 22 func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { 23 // Called when the user discards a scene session. 24 // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 25 // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 26 } 27 28 29}

SceneDelegateがwindowプロパティを持っているようなので、
ここでrootViewControllerの設定をしました。
色々変わっていたのでこちらを参考にさせていただきました。

Swift

1class SceneDelegate: UIResponder, UIWindowSceneDelegate { 2 3 var window: UIWindow? 4 5 6 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 7 // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 8 // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 9 // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 10 guard let _ = (scene as? UIWindowScene) else { return } 11 12 if let windowScene = scene as? UIWindowScene { 13 let window = UIWindow(windowScene: windowScene) 14 window.rootViewController = CodeViewController(nibName: nil, bundle: nil) 15 self.window = window 16 window.makeKeyAndVisible() 17 } 18 } 19 20 func sceneDidDisconnect(_ scene: UIScene) { 21 // Called as the scene is being released by the system. 22 // This occurs shortly after the scene enters the background, or when its session is discarded. 23 // Release any resources associated with this scene that can be re-created the next time the scene connects. 24 // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 25 } 26 27 func sceneDidBecomeActive(_ scene: UIScene) { 28 // Called when the scene has moved from an inactive state to an active state. 29 // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 30 } 31 32 func sceneWillResignActive(_ scene: UIScene) { 33 // Called when the scene will move from an active state to an inactive state. 34 // This may occur due to temporary interruptions (ex. an incoming phone call). 35 } 36 37 func sceneWillEnterForeground(_ scene: UIScene) { 38 // Called as the scene transitions from the background to the foreground. 39 // Use this method to undo the changes made on entering the background. 40 } 41 42 func sceneDidEnterBackground(_ scene: UIScene) { 43 // Called as the scene transitions from the foreground to the background. 44 // Use this method to save data, release shared resources, and store enough scene-specific state information 45 // to restore the scene back to its current state. 46 } 47 48 49}

この状態でMainのStoryboardを削除したところ質問者様と同じ

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle

上記のエラーが出たので、
XcodeのMain Interfaceを空にして、
info.plistのScene ConfigurationStoryboard Nameの項目を削除しました。

info.plist

これで一応エラーなしで起動することができました。

正直まだ正しい対応なのか確証が持てていないので、もう少し調査する必要があるかもしれません。
曖昧な回答しかできず申し訳ありません。

投稿2019/10/02 01:34

編集2019/10/03 03:24
hayabusabusash

総合スコア767

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lady-navigation

2019/10/03 01:51

ご回答ありがとうございます。 そちらも確認しましたが、Mainではなく空白になっています。
hayabusabusash

2019/10/03 02:11

確認ありがとうございます。 SceneDelegateのせいで色々やらないといけないことが増えたみたいですね。 その辺追えてませんでした、申し訳ないです。 ひとまずAppDelegateってどうなってるのか見せていただくことはできますか?
lady-navigation

2019/10/03 02:19

AppDelegate.swiftを追記いたしました。
hayabusabusash

2019/10/03 02:23

ありがとうございます。 あと一応確認なんですが、XcodeのDeployment InfoのTargetってiOS12以下ですよね?
lady-navigation

2019/10/03 02:33

iOS13になっています。 https://qiita.com/omochimetaru/items/31df103ef98a9d84ae6b こちらを参考にし、iOS13以降はAppDelegateに書いている処理が実行されなくなるのでSceneDelegateに処理を書かなければならないと解釈しました。だから上記のQiitaではelse文を使ってiOS13じゃない時にだけAppDelegateの方の実行させているのだと思っていました。
hayabusabusash

2019/10/03 02:45

私も関連の記事をみましたが、 問題になるのはXcode11でiOS12.x以下をターゲットにしたプロジェクトを作成した場合に発生するものだと思います。 もともとiOS13をターゲットにしたプロジェクトを作った場合は上記の問題は発生しないためデフォルトのままで問題ないと思います。 手元でコードから生成したViewControllerをRootにして動かすことができたのでもう少し回答に追記しますね。
lady-navigation

2019/10/03 03:31

info.plistのScene ConfigulationのStoryboard Mainを消したらできました! たいへん丁寧なご回答、本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問