イタリックテキスト### 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
絞り込みボタンはCollectionView上(のセル)に乗っていて、そのコードが質問内のコードでしょうか?
はい、それで合っています。メルカリアプリのカテゴリー選択をするボタンをイメージしてもらえますでしょうか。
メルカリアプリは使ったことがないのでイメージできませんが、それはまぁいいです。落ちている箇所のコードを書いてもらえますか?
データ取得した後、TableViewのリロードしてますか?その辺のコードも見てみたいのですが。(self.strを更新している箇所)
reloadしているコードを追加しました。セキュリティ上全てのコードをお見せ出来なくて申し訳ありません。
「データ取得 → self.strを更新 → リロード」の流れを知りたいのです。この三つの処理は一気にやってますか?
tableviewの中身を入れ替えるタイミングが問題で、「データ取得・NSArrayに入れる・リロード」は一気にやっております。ボタンタップ時に「NSArrayを空にする・データ取得・NSArrayに入れる・リロード」の慣性スクロール中にNSArrayを空にするの処理を行うところでout of rangeになってしまうので良い方法が無いかを考えております。
空にしているなら、そのときにもリロードしないとまずいですね。なぜ空にしているのでしょうか?
同じ画面で表示しているデータを入れ替えたいので空にしています。 空にしないと前のデータに追加されることになるので
上書きすればいいのでは?
配列の初期化タイミングをAPI取得後に変更し、一連の流れでデータ更新するようにしました。 また、絞り込みボタンをタップした時に慣性スクロールを短くする処理も入れることにより、よほどの無茶な操作がない限り。通常の操作では落ちなくなりました。
回答1件
あなたの回答
tips
プレビュー