質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

1回答

1503閲覧

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value の解決方法

noblehorse

総合スコア6

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2018/09/18 05:50

iOSアプリ開発を行い、SNSでよく目にする検索して何かを探し出すという機能のアプリ開発を行なっているのですが、途中でエラーが出てしまい、シミュレーター実装まで辿りつきませんでした。
エラー表示は下記のように表示されています。

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

tableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: self.view.frame.width, height: self.view.frame.height)) //ここの部分にエラー表示

エラー文章を翻訳するとオプショナル値で設定しているコードの中にNilが発生してしまうというような内容だと自分で解釈させていただいたのですがそれを踏まえた上で結局直すことはできませんでした。

###エラー原因
元々はコードを主体として開発を行っていたのですが視覚的に見やすくしたいと思い、
コードのみでのシミュレーター実装ができる状態に仕上げてからストーリーボードを使い、
UI部品を接続し、接続時のコードと被っているコードを消していくという作業をしていった際にどこかでNilが発生してしまったのだと思います。

###コード

import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate { @IBOutlet weak var searchBar: UISearchBar! @IBOutlet weak var tableView: UITableView! @IBOutlet weak var tableViewCell: UITableViewCell! //検索データ let kensaku:[String] = [] var searchResults:[String] = [] override func viewDidLoad() { super.viewDidLoad() //tableViewのカスタマイズ let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height //エラー部分 tableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: self.view.frame.width, height: self.view.frame.height)) tableView.register(UITableViewCell.self, forCellReuseIdentifier: "tableViewCell") tableView.dataSource = self tableView.delegate = self self.view.addSubview(tableView) //searchBarのカスタマイズ searchBar = UISearchBar() searchBar.delegate = self searchBar.frame = CGRect(x:0, y:0, width:self.view.frame.width, height:42) searchBar.layer.position = CGPoint(x: self.view.bounds.width/2, y: 89) searchBar.searchBarStyle = UISearchBarStyle.default searchBar.showsSearchResultsButton = false searchBar.placeholder = "検索" searchBar.setValue("キャンセル", forKey: "_cancelButtonText") searchBar.tintColor = UIColor.red tableView.tableHeaderView = searchBar } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //データの個数を返すメソッド func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if searchBar.text != "" { return searchResults.count } else { return kensaku.count } } //tableViewCellの作成&検索結果表示 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) if searchBar.text != "" { cell.textLabel!.text = "(searchResults[indexPath.row])" } else { cell.textLabel!.text = "(kensaku[indexPath.row])" } return cell } // 検索ボタンが押された時に呼ばれる func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { self.view.endEditing(true) searchBar.showsCancelButton = true self.searchResults = kensaku.filter{ // 大文字と小文字を区別せずに検索 $0.lowercased().contains(searchBar.text!.lowercased()) } self.tableView.reloadData() } // キャンセルボタンが押された時に呼ばれる func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { searchBar.showsCancelButton = false self.view.endEditing(true) searchBar.text = "" self.tableView.reloadData() } // テキストフィールド入力開始前に呼ばれる func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool { searchBar.showsCancelButton = true return true } }

###エラーをなくすために試したこと

1、継承部分の変更

@IBOutlet weak var tableView: UITableView!

           ↓tableViewの継承部分を変更

・!→?
@IBOutlet weak var tableView: UITableView**?**

・継承(:)から代入(=)に
@IBOutlet weak var tableView = UITableView**!**

・!→()
@IBOutlet weak var tableView = UITableView**()**

これらに変更してみましたが、変更すると他のコードにエラーが出てしまい解決することができませんでした。

2、エラー部分のコードを消す

・エラー部分のコードを消しても違う部分にエラーが出てしまい、その繰り返しになってしまいました。

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

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

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

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

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

guest

回答1

0

おそらくアンラップに失敗しているのはself.viewです。

どのようにViewControllerを生成しているか不明ですが、storyboardなどから生成される場合以外はviewは自動では生成されません。

エラーの行の前に

swift

1 2if self.view == nil { 3 fatalError("view is not valid.") 4}

を入れてみてfatalErrorの行で止まる場合はviewが生成されていません。

投稿2018/09/18 08:45

MasakiHori

総合スコア3384

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

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

noblehorse

2018/09/21 06:39

コードのほう入力させていただきましたがMasakiHori様の言う通り、fatalErrorで止まってしまったためviewが生成されていないであろうということがわかりました。ここで分からないことがあったのですが、初期に設定されているViewControllerのViewはself.viewの対象外にということでしょうか? 質問の中ですでに間違っていることがありましたら申し訳ありません。
MasakiHori

2018/09/21 07:49

UIViewControllerが生成された時はviewはnilです。 初期に設定されているviewはありません。 ただし、storyboadなどから生成された場合は、storyboard上の設定が反映されます。この場合もstoryboard上の設定が誤っていればnilとなります。
noblehorse

2018/09/23 11:59

そうなんですね! storyboard上から設定した部品ははじめから配置されているViewControllerのsafe Area全体にtableViewを配置し、そのヘッダーにseach Barを配置した形になります。だからエラーになってしまっているのかもしれません。 ここからエラーをなくすためにはViewControllerのViewに何か設定をすれば解決できるのでしょうか?または新たにViewを配置したりするなどの他の方法が必要でしょうか? ご教授願いします!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問