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

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

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

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

Q&A

解決済

2回答

6671閲覧

celloctionViewのcellの削除

RyoTamura

総合スコア19

Swift

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

0グッド

0クリップ

投稿2017/08/02 03:38

編集2017/08/02 07:57

collectionViewを使い選択した画像を表示させるようにしています。
画像を追加する際には

swift

1imageArray.append(image) 2collectionView.reloadData()

でうまく表示できたのですが、削除する際に

swift

1imageArray.remove(at: indexPath.row) 2collectionView.reloadData()

とするとエラーが発生してしまいます。
データ元の方は削除できているので、collectionViewのCellの数に問題があると思われるのですが解決策がわかりません。

performBatchUpdate()を使うという情報を見つけましたが、update(() -> void)の箇所に何を入力すればいいのか理解できませんでした。

エラー内容
イメージ説明

発生場所
イメージ説明

削除コード場所
アクションシートを使って画像を削除しようとしています。
イメージ説明

collectionViewのレイアウト
レイアウトは自作のものを使っています。

swift

1import UIKit 2 3class TestCollectionViewLayout: UICollectionViewLayout { 4 5 let numberColumns = 2 //列数 6 var height:CGFloat = 200 //セルの高さ 7 8 //レイアウト配列 9 private var layoutData = [UICollectionViewLayoutAttributes]() 10 11 //レイアウトを準備するメソッド 12 override func prepare() { 13 //全体の幅 14 let allWidth = collectionView!.bounds.width - collectionView!.contentInset.left - collectionView!.contentInset.right 15 16 let widthSecond = collectionView!.frame.width ///多分使わない 17 18 //列の幅 19 let columnWidth = widthSecond / CGFloat(numberColumns) ///元はallwidth 20 height = columnWidth 21 22 23 //座標 24 var y:CGFloat = 0 25 var x:CGFloat = 0 26 27 //要素数ぶんループ 28 for count in 0 ..< collectionView!.numberOfItems(inSection: 0) { 29 30 let indexPath = NSIndexPath(item:count, section:0) 31 32 //レイアウトの配列に位置とサイズを登録する。 33 let frame = CGRect(x:x, y:y, width:columnWidth, height: height) 34 let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath) 35 attributes.frame = frame 36 layoutData.append(attributes) 37 38 //X座標を更新 39 if(count % 2 == 0) { 40 x = columnWidth 41 } else { 42 x = 0 43 } 44 45 46 //Y座標を更新 47 if(count % 2 != 0){ 48 y = y + height 49 } 50 } 51 } 52 53 54 55 //レイアウトを返すメソッド 56 override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 57 return layoutData 58 } 59 60 61 62 //全体サイズを返すメソッド 63 override var collectionViewContentSize:CGSize { 64 //全体の幅 65 let allWidth = collectionView!.bounds.width - collectionView!.contentInset.left - collectionView!.contentInset.right 66 67 let widthSecond = collectionView!.frame.width///この辺いじった 68 height = widthSecond / CGFloat(numberColumns) 69 70 //全体の高さ 71 let allHeight = CGFloat(collectionView!.numberOfItems(inSection: 0)) * height / 2 72 73 return CGSize(width:widthSecond, height:allHeight) ////いじった 74 } 75 76} 77

collectionViewは1つだけです。

コンソール情報
btと入力した結果の全文です。

swift

1* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT 2 frame #0: 0x000000010da29d42 libsystem_kernel.dylib`__pthread_kill + 10 3 frame #1: 0x000000010da61457 libsystem_pthread.dylib`pthread_kill + 90 4 frame #2: 0x000000010d7bb88f libsystem_c.dylib`abort + 127 5 frame #3: 0x000000010cc9bce5 libc++abi.dylib`abort_message + 245 6 frame #4: 0x000000010ccb6cbd libc++abi.dylib`default_terminate_handler() + 265 7 frame #5: 0x000000010a3923c4 libobjc.A.dylib`_objc_terminate() + 103 8 frame #6: 0x000000010ccb3f29 libc++abi.dylib`std::__terminate(void (*)()) + 8 9 frame #7: 0x000000010ccb3bbe libc++abi.dylib`__cxa_rethrow + 99 10 frame #8: 0x000000010a3922dc libobjc.A.dylib`objc_exception_rethrow + 40 11 frame #9: 0x000000010a8b8096 CoreFoundation`CFRunLoopRunSpecific + 534 12 frame #10: 0x000000010e9cfa24 GraphicsServices`GSEventRunModal + 62 13 frame #11: 0x000000010b43a134 UIKit`UIApplicationMain + 159 14 * frame #12: 0x0000000108961877 cellectionView`main at AppDelegate.swift:13 15 frame #13: 0x000000010d71365d libdyld.dylib`start + 1 16 frame #14: 0x000000010d71365d libdyld.dylib`start + 1

情報不足で申し訳ありません。よろしくお願いいたします。

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

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

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

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

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

fuzzball

2017/08/02 03:56

エラー内容と発生場所を書いて下さい。また、削除コードをどこに書いているかも書いて下さい。
fuzzball

2017/08/02 06:02 編集

アクションシートを使わずに、collectionView(_:didHighlightItemAt:)の冒頭で削除処理を行っても同じでしょうか? あと、Tak1016さんの回答は試していないのでしょうか?
RyoTamura

2017/08/02 06:43

アクションシート無しでも同じでした。
MasakiHori

2017/08/02 07:19

collectionView(_:didHighlightItemAt:)で該当セルを削除する(データの削除とreloadDataを呼ぶ)のがまずいのではないでしょうか? 遅延実行してみればどうでしょう?
RyoTamura

2017/08/02 07:32

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0)を使って1秒遅れでやってみたのですが、同様のエラーが発生してしまいました。
fuzzball

2017/08/02 07:34 編集

質問に書かれている情報だけで検証してみましたが問題なく削除出来ました。CollectionViewのレイアウトに関する情報を書いて下さい。(他にも書いた方が良さそうな情報があったら書いて下さい)あと、CollectionViewは画面上に一つだけでしょうか?
fuzzball

2017/08/02 07:40

もう一つ。止まったとき、Consoleに bt (Enter) と入力して表示される一覧を書いて下さい。(長過ぎるようなら後半は省略してもかまいません)
guest

回答2

0

ベストアンサー

ちょっとググっただけですが、

swift

1collectionView.reloadData() 2collectionView.collectionViewLayout.invalidateLayout()

で直りますか?

参考URL
iOS 10 bug: UICollectionView received layout attributes for a cell with an index path that does not exist

【追記】

TestCollectionViewLayout.prepare()内のループの前に、

swift

1layoutData.removeAll()

を追加して下さい。

投稿2017/08/02 04:48

編集2017/08/02 08:32
fuzzball

総合スコア16731

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

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

RyoTamura

2017/08/02 05:39

直りませんでした。同じエラーが発生してしまいます。
Tak1016

2017/08/02 07:00

print("削除")を宣言しているハンドラの中で print(indexPath.row)をしてみてください。 didHighlightedのメソッドの先頭で宣言している print(indexPath.row) と同じrowでしょうか。そしてimageArrayにはそのindexは存在しますか? handler内部にブレークポイントを貼ってデバッグしてみて下さい。
RyoTamura

2017/08/02 07:17

はい。同じrowです。 imageArrayの削除だけならエラーが出ません。中身を確認しても意図したものが削除されています。 ただ、そこでcollectionView.reloadData()をするとエラーが発生してしまいます。 collectionView.reload()のみを返すButtonを作成し 1: didiHighlited内のactionsheetでimageArray[indexPath.row]を削除 2: buttonをタップしてcollectionView.reloadData() という実験したのですが、その時はcollectionViewのcellが正常に減っていました。
fuzzball

2017/08/02 07:31

>>Tak1016さん handlerの中はメインスレッドです。
fuzzball

2017/08/02 08:31

回答に追記しました。
RyoTamura

2017/08/03 11:40

layoutData.removeAll() を追加したらできるようになりました!! 本当にありがとうございます。 今回のエラーの原因は自作レイアウトにあったのですね。 簡潔でもいいので、なぜエラー原因を発見できたのか教えていただきたいです。
fuzzball

2017/08/03 15:06

症状を再現出来たので、とりあえずprint文をあちこちに埋め込んだのですが、ループを抜けたところの print(layoutData) (実際にはindexPathのみ表示)を見て原因が分かりました。
guest

0

https://developer.apple.com/documentation/uikit/uicollectionview/1618060-deleteitems

UICollectionView のdeleteItems(at: [indexPath])
を使うとどうでしょう?

投稿2017/08/02 04:06

編集2017/08/02 04:08
Tak1016

総合スコア1408

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

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

RyoTamura

2017/08/02 06:43

やってみましたが、同じエラーが発生してしまいました。
Tak1016

2017/08/02 07:27

ごめんなさいこっちでした。 mainスレッドにしないといけないのかも? // メインスレッドで実行 DispatchQueue.main.async { collectionView.reloadData() }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問