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

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

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

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

Swift

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

Q&A

解決済

2回答

1028閲覧

Index out of rangeがでる

daimyon

総合スコア3

TableView

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

Swift

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

0グッド

0クリップ

投稿2020/10/17 08:08

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
シュミレーターでTableViewを表示する時に
return name[section].count
のところにエラーが出ます
解決方法を教えてほしいです。

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

Fatal error: Index out of range

該当のソースコード

swift

1 2import UIKit 3 4class YearTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 5 6 private let YearTableViewCell = "YearTableViewCell" 7 private let Era = [ 8 "奈良", "平安", "鎌倉", "室町", "安土桃山", "江戸", "明治" 9 ] 10 private let name = [ 11 ["784年長岡京遷都", "794年平安京遷都"], ["802年\n坂上田村麻呂を征夷大将軍に任命", "aaa"], 12 ["aaa"], 13 ["aaa"] 14 15 ] 16 17 @IBOutlet weak var YearTableView: UITableView! 18 19 override func viewDidLoad() { 20 super.viewDidLoad() 21 22 YearTableView.dataSource = self 23 YearTableView.delegate = self 24 YearTableView.register(UITableViewCell.self, forCellReuseIdentifier: "YearTableViewCell") 25 } 26 27 28 func numberOfSections(in tableView: UITableView) -> Int { 29 return Era.count 30 } 31 32 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 33 return name[section].count 34 } 35 36 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 37 let cell = YearTableView.dequeueReusableCell(withIdentifier: YearTableViewCell, for: indexPath) 38 cell.textLabel?.text = name[indexPath.section][indexPath.row] 39 cell.textLabel?.numberOfLines = 2 40 41 return cell 42 } 43 44 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 45 return 60 46 } 47 48 //header 49 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 50 let label = UILabel() 51 label.text = Era[section] 52 label.textAlignment = .center 53 label.backgroundColor = .gray 54 55 return label 56 } 57 58 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 59 return 50 60 } 61 62 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 63 print("section: (indexPath.section), row: (indexPath.row)") 64 tableView.deselectRow(at: indexPath, animated: true) 65 66 67 } 68 69} 70

試したこと

Webで調べたものを試しましたが直りませんでした

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

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

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

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

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

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

guest

回答2

0

ベストアンサー

範囲外、という意味では y_waiwai さんのご指摘通りなのですが、コード上の原因としては、セクションに表示する時代区分の数と、各元号における出来事(の配列数)が一致していないことにあります。

表示する時代区分は

Swift

1 private let Era = [ 2 "奈良", "平安", "鎌倉", "室町", "安土桃山", "江戸", "明治" 3 ] 4```Swift 5 6**7**ありますが、一方出来事の数は 7 8```Swift 9 private let name = [ 10 // 奈良時代 11 ["784年長岡京遷都", "794年平安京遷都"], 12 // 平安時代 13 ["802年\n坂上田村麻呂を征夷大将軍に任命", "aaa"], 14 // 鎌倉時代? 15 ["aaa"], 16 // 室町時代 17 ["aaa"] 18 // 安土桃山、江戸、明治に対応する出来事がない 19 ]

という具合に、4つしか存在しません。

なので、安土桃山時代以降の出来事を表示しようとしても、対応するデータがないためエラーが出てしまっています。

なので、両方の数が一致するようにするのが解決方法となります。

Swift

1 private let Era = [ 2 "奈良", "平安", "鎌倉", "室町", "安土桃山", "江戸", "明治" 3 ] 4 5 private let name = [ 6 // 奈良時代 7 ["784年\n長岡京遷都", "794年\n平安京遷都"], 8 // 平安時代 9 ["802年\n坂上田村麻呂を征夷大将軍に任命", "1069年\n後三条天皇が桑園の整理を行う"], 10 // 鎌倉時代 11 ["1192年\n源頼朝が征夷大将軍になる"], 12 // 室町時代 13 // 何もなければ空配列をいれるß 14 [], 15 // 安土桃山時代 16 ["1590年\n豊臣秀吉が全国を統一する"], 17 // 江戸時代 18 ["1603年\n徳川家康が征夷大将軍になる"], 19 // 明治時代 20 ["1889年\n大日本帝国憲法発布"] 21 ]

こういう具合に、表示する項目数を一致させれば、問題なく表示することが可能となります。

しかし、これだと時代区分を追加するたびに両者が一致しているか否か考えなければなりません。

たとえば、時代区分に「飛鳥時代」を追加したあとは、出来事の欄にも飛鳥時代の出来事を忘れずに追加する必要があります。

また、時代区分における「飛鳥時代」の場所と、出来事における「飛鳥時代」の場所も一致させなければ、時代区分と出来事が一致しない原因にもなります。

このようなことを避けるためには、データを管理するためのクラスを作ったり、あるいはタプルを使って両者を一括して管理するのが良いのではないでしょうか。

Swift

1 // 例えば、タプルを使って一つの時代を管理する 2 // ("時代区分", ["出来事1", "出来事2", "..."]) 3 4 let history:[(era: String, events: [String])] = [ 5 ("奈良", ["784年\n長岡京遷都", "794年\n平安京遷都"]), 6 ("平安", ["802年\n坂上田村麻呂を征夷大将軍に任命", "1069年\n後三条天皇が桑園の整理を行う"]), 7 ("鎌倉", ["1192年\n源頼朝が征夷大将軍になる"]), 8 ("室町", ["1467年\n応仁の乱"]), 9 ("安土桃山", ["1590年\n豊臣秀吉が全国を統一する"]), 10 ("江戸", ["1603年\n徳川家康が征夷大将軍になる"]), 11 ("明治", ["1889年\n大日本帝国憲法発布"]) 12 ] 13 14 func numberOfSections(in tableView: UITableView) -> Int { 15 // 時代の数 16 return history.count 17 } 18 19 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 20 // 各セクション(時代)に含まれる出来事の数 21 return history[section].events.count 22 } 23 24 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 25 let cell = YearTableView.dequeueReusableCell(withIdentifier: YearTableViewCell, for: indexPath) 26 27 // ある時代(indexPath.section) で指定された時代の出来事を表示する 28 cell.textLabel?.text = history[indexPath.section].events[indexPath.row] 29 cell.textLabel?.numberOfLines = 2 30 31 return cell 32 } 33 34 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 35 let label = UILabel() 36 37 // ある時代の元号を出力する 38 label.text = history[section].era 39 label.textAlignment = .center 40 label.backgroundColor = .gray 41 42 return label 43 } 44

投稿2020/10/18 03:56

編集2020/10/24 13:23
TsukubaDepot

総合スコア5086

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

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

daimyon

2020/10/24 13:21

解決しました ありがとうございます!
guest

0

Fatal error: Index out of range

配列の範囲外のアクセス、と言うエラーなので、そのエラーが出るときのsectionの数値を調べてみよう

投稿2020/10/17 10:46

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問