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

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

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

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

Xcode

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

Swift

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

Q&A

解決済

1回答

2899閲覧

UITableViewCellのエラーについて

Kuma44

総合スコア9

TableView

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/08/16 07:05

前提・実現したいこと

storyboardを使用せずにコードで入力してますが、カスタムセルの設定のみ「xib」を作成してやっています。

エラーが出てるので解消してtableに表示させたいです。

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

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

該当のソースコード

swift4 import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { /// 画像のファイル名 let imageNames = ["1.png", "2.png", "3.png"] /// 画像のタイトル let imageTitles = ["001", "002", "003"] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let myTableView = UITableView(frame: view.frame, style: .plain) myTableView.rowHeight = 70 myTableView.delegate = self myTableView.dataSource = self myTableView.register(CustomCellTableViewCell.self, forCellReuseIdentifier: NSStringFromClass(CustomCellTableViewCell.self)) self.view.addSubview(myTableView) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /// セルの個数を指定するデリゲートメソッド(必須) func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return imageNames.count } /// セルに値を設定するデータソースメソッド(必須) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // セルを取得 let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(CustomCellTableViewCell.self), for: indexPath) as! CustomCellTableViewCell // セルに値を設定 cell.setCell(imageName: imageNames[indexPath.row], titleText: imageTitles[indexPath.row]) return cell } }
swift4 import UIKit class CustomCellTableViewCell: UITableViewCell { var myImage: UIImage! @IBOutlet weak var myImageView: UIImageView! @IBOutlet weak var myLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } /// 画像・タイトルを設定するメソッド func setCell(imageName: String, titleText: String) { myImageView.image = UIImage(named: imageName) //ここでエラー myLabel.text = titleText //ここでもエラー } }

試したこと

myImageView.image = UIImage(named: imageName) //ここでエラー myLabel.text = titleText //ここでもエラー

の部分を

myImage = UIImage(named: imageName) myImageView = UIImageView(image: myImage) myLabel?.text = titleText //ここでもエラー

にしたところエラーは消えましたが画像やラベルの表示がされませんでした。

補足情報(FW/ツールのバージョンなど)

Xcode : Version 9.4.1
Swift4.1.2

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

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

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

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

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

xAxis

2018/08/17 05:35

.xib内においてCustomClassはどちらに設定されていますか?
Kuma44

2018/08/19 03:20

「CustomCellTableViewCell」で設定しています。
xAxis

2018/08/19 08:33

聞き方が悪かったですかね。File's OwnerのCusotomClassかCellのCustomClass、どちらに設定されていますか?
guest

回答1

0

ベストアンサー

今回の回答ではどこに何をどうやって設定するかが大事です。TableViewをコードで、CustomCellは.xibで、となってますから全てをstoryboardで設定するのとはやり方が変わってきます。また、UINibやIdentifierの知識も深める必要があるでしょう。

まず.xibファイルをみていきます。今回のやり方ではFile's OwnerのCustom Classには設定をしません。空のままにしておきます。じゃあどこにCustom Classを設定するのかというとCellに対して設定を行います。またCellのIdentifierも空にしておきます。

あまり関係がありませんが、CustomCellTableViewCellの名前はもう少し短くした方がいいんじゃないかと個人的には思います。CustomCellとか。

んでそのCustomCellTableViewCellですが、回答に書かれているコードには全角スペースが紛れ込んでいた様なので注意した方がいいです。のちにコードを貼りますがそのコードでは修正しています。

そして本丸のViewControllerですがtableView.register(_:forCellReuseIdentifier:)する時のNibNameはCustomCellTableViewCellのクラス名が入ります。そして第二引数にはCellのIdentifierを入れます。このCellのIdentifier、クラス名は使えません。コードでは分かりやすくハードコーディングしてます。
またtableView.dequeReusableCell(withIdentifier:)ですがここのIdentifierは上記のtableView.register(_:forCellReuseIdentifier:)の第二引数のIdentifierを指定します。

以上で動く様になるでしょう。動作は確認済みです。

コード(修正後)

swift

1import UIKit 2 3class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 4 5 /// 画像のファイル名 6 let imageNames = ["1.png", "2.png", "3.png"] 7 /// 画像のタイトル 8 let imageTitles = ["001", "002", "003"] 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 // Do any additional setup after loading the view, typically from a nib. 13 let myTableView = UITableView(frame: view.frame, style: .plain) 14 myTableView.rowHeight = 70 15 myTableView.delegate = self 16 myTableView.dataSource = self 17 let myNib = UINib(nibName: "CustomCellTableViewCell", bundle: nil) //.xibファイルと同名をnibNameに入れる 18 myTableView.register(myNib, forCellReuseIdentifier: "TableViewCell") //IdentifierはCellのもの。クラス名と同一のものは使えない。 19 self.view.addSubview(myTableView) 20 21 } 22 23 override func didReceiveMemoryWarning() { 24 super.didReceiveMemoryWarning() 25 // Dispose of any resources that can be recreated. 26 } 27 28 29 /// セルの個数を指定するデリゲートメソッド(必須) 30 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 31 return imageNames.count 32 } 33 34 /// セルに値を設定するデータソースメソッド(必須) 35 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 36 // セルを取得 37 //let cell = tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(CustomCellTableViewCell.self), for: indexPath) as! CustomCellTableViewCell 38 guard let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as? CustomCellTableViewCell else { //registerした時のidentifierをここに 39 fatalError() 40 } 41 42 // セルに値を設定 43 cell.setCell(imageName: imageNames[indexPath.row], titleText: imageTitles[indexPath.row]) 44 45 return cell 46 } 47 48}

swift

1import UIKit 2 3class CustomCellTableViewCell: UITableViewCell { 4 5 var myImage: UIImage! 6 @IBOutlet var myImageView: UIImageView! 7 8 @IBOutlet var myLabel: UILabel! 9 override func awakeFromNib() { 10 super.awakeFromNib() 11 // Initialization code 12 } 13 14 override func setSelected(_ selected: Bool, animated: Bool) { 15 super.setSelected(selected, animated: animated) 16 17 // Configure the view for the selected state 18 } 19 20 func setCell(imageName: String, titleText: String) { 21 myImageView.image = UIImage(named: imageName) //ここでエラー 22 myLabel.text = titleText//ここでもエラー ←全角スペースが紛れ込んでました 23 } 24 25}

余談

reusableCellを生成する時、質問ではas!としていましたが上記の様にguard文を使った方がいいです。上記のguard文ではダウンキャスト失敗した時には強制終了する様になっています。それの何がいいのかというと、どこが間違っているのかが分かりやすいからです。Cellの生成に失敗していることが分かるということは、CustomCellTableViewCell内に問題がない可能性が高くなります。となると考えるはregister周辺だったりともう少し上の行程で問題があることが分かります。なのでas!とした場合よりも問題解決が早まることを期待できるでしょう。

投稿2018/08/19 09:04

xAxis

総合スコア1349

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

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

Kuma44

2018/08/20 11:25

とてもわかりやすく説明していただきましてありがとうございます! 初心者でまだ理解できない部分もあるので熟読させていただきます。
xAxis

2018/08/20 11:27

自分の説明、もっとシンプルにかけたらベストなのですけどね。分からない部分があったらコメント欄にどうぞ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問