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

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

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

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

Swift

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

Q&A

解決済

1回答

642閲覧

API通信時のUITableViewでのIndex out of range

komechi

総合スコア19

iOS

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

Swift

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

0グッド

0クリップ

投稿2018/11/22 04:13

編集2018/11/22 08:10

イタリックテキスト### API通信を伴うTableViewでの絞り込み

APIでJSONデータを取得し、tableviewに表示するアプリをswiftで作っています。
絞り込み(ボタンをタップ)すると、絞り込み条件に従ってAPIでJSONデータを再取得するのですが、
慣性スクロール中に絞り込みボタンをタップするとIndex out of rangeでアプリが落ちます。
Cellの再利用の問題で当たり前と言えばそうなのですが、これを回避する良い方法はないでしょうか?

1、慣性スクロー中はボタンを無効にする
2、ボタンタップ時に慣性スクロールを停止する

あたりかなと思いますが、2番を実現する方法がわかりません。

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

Fatal error: Index out of range

該当のソースコード

swift4

1func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 2 self.collectioncellcolor = collection[indexPath.row] 3 4 searchitem.decelerationRate = 0.01 5 6 self.str = [String]() 7 self.str2 = [String]() 8 self.str3 = [String]() 9 self.str4 = [String]() 10 self.str5 = [String]() 11 self.str6 = [Int]() 12 self.pageng = 0 13 14 if collection[indexPath.row] != "ALL" { 15 searchword = " !-" + collection[indexPath.row] 16 }else{ 17 searchword = "" 18 } 19 getapi() 20 21 } 22 23 24// 落ちる箇所のコード 25func tableView(_ table: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 26 27 if let cell = table.dequeueReusableCell(withIdentifier: "CustomCell") as? TableViewCell3 { 28 29 30 cell.contentView.backgroundColor = UIColor(red: 248/255, green: 235/255, blue: 241/255, alpha: 100/100) 31 32 cell.start.rating = Double(self.str[indexPath.row]) ?? 0 <-- ここ 慣性スクロール中にindexPathがnilになる 33 34 35//テーブルをリロードする箇所 36private var apisearchend:String!{ 37 didSet{ 38 DispatchQueue.global().async { 39 DispatchQueue.main.async { 40 41 self.searchitem.reloadData() 42

試したこと

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

swift4

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

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

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

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

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

fuzzball

2018/11/22 06:38

絞り込みボタンはCollectionView上(のセル)に乗っていて、そのコードが質問内のコードでしょうか?
komechi

2018/11/22 06:41

はい、それで合っています。メルカリアプリのカテゴリー選択をするボタンをイメージしてもらえますでしょうか。
fuzzball

2018/11/22 06:43

メルカリアプリは使ったことがないのでイメージできませんが、それはまぁいいです。落ちている箇所のコードを書いてもらえますか?
fuzzball

2018/11/22 07:06 編集

データ取得した後、TableViewのリロードしてますか?その辺のコードも見てみたいのですが。(self.strを更新している箇所)
komechi

2018/11/22 08:11

reloadしているコードを追加しました。セキュリティ上全てのコードをお見せ出来なくて申し訳ありません。
fuzzball

2018/11/22 08:44

「データ取得 → self.strを更新 → リロード」の流れを知りたいのです。この三つの処理は一気にやってますか?
komechi

2018/11/22 09:08

tableviewの中身を入れ替えるタイミングが問題で、「データ取得・NSArrayに入れる・リロード」は一気にやっております。ボタンタップ時に「NSArrayを空にする・データ取得・NSArrayに入れる・リロード」の慣性スクロール中にNSArrayを空にするの処理を行うところでout of rangeになってしまうので良い方法が無いかを考えております。
fuzzball

2018/11/22 09:30

空にしているなら、そのときにもリロードしないとまずいですね。なぜ空にしているのでしょうか?
komechi

2018/11/22 09:51

同じ画面で表示しているデータを入れ替えたいので空にしています。 空にしないと前のデータに追加されることになるので
fuzzball

2018/11/22 10:40

上書きすればいいのでは?
komechi

2018/11/22 11:19

配列の初期化タイミングをAPI取得後に変更し、一連の流れでデータ更新するようにしました。 また、絞り込みボタンをタップした時に慣性スクロールを短くする処理も入れることにより、よほどの無茶な操作がない限り。通常の操作では落ちなくなりました。
guest

回答1

0

自己解決

配列の初期化タイミングをAPI取得後に変更し、一連の流れでデータ更新するようにしました。
また、絞り込みボタンをタップした時に慣性スクロールを短くする処理も入れることにより、よほどの無茶な操作がない限り。通常の操作では落ちなくなりました。

投稿2018/11/22 11:19

komechi

総合スコア19

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問