功能
用 UICollectionView 实现两个 cell 之间的位置交互或者拖拽某个位置删除
问题
iOS 11 以上拖拽删除会崩溃,在 iOS 9、10 都没有问题
错误
017-10-11 11:38:02.692004+0800 MOCR[2585:1047221] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempting to invalidate an item at an invalid indexPath: <NSIndexPath: 0x1c442a680> {length = 2, path = 0 - 1} globalIndex: 1 numItems: 1'
*** First throw call stack:
(0x181f3bd38 0x181450528 0x181f3bc0c 0x1828cac24 0x18be1091c 0x18bdd2ab8 0x18b4b74ac 0x18b4b48b8 0x18b569a4c 0x18bdd9e98 0x10275d49c 0x10275d45c 0x102762050 0x181ee3f20 0x181ee1afc 0x181e022d8 0x183c93f84 0x18b3af880 0x1009a753c 0x18192656c)
libc++abi.dylib: terminating with uncaught exception of type NSException
代码
func
handleLongGesture
(
gesture
:
UILongPressGestureRecognizer
) {
switch
(
gesture
.
state
) {
case
.
began
:
guard
let
selectedIndexPath
=
self
.
collectionView
.
indexPathForItem
(
at
:
gesture
.
location
(
in
:
self
.
collectionView
))
else
{
break
}
collectionView
.
beginInteractiveMovementForItem
(
at
:
selectedIndexPath
)
case
.
changed
:
collectionView
.
updateInteractiveMovementTargetPosition
(
gesture
.
location
(
in
:
gesture
.
view
!))
case
.
ended
:
self
.
collectionView
.
endInteractiveMovement
()
// 检测是否删除操作,是的话删除数据并调用 reloadData()
default
:
collectionView
.
cancelInteractiveMovement
()
}
}
|
分析
测试发现调用 beginInteractiveMovementForItem 和 endInteractiveMovement 也会触发 reloadData 操作,这样删除前后会调用两次 reloadData,但是 reloadData 又是异步操作,所以就报错了。
解决
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
func
handleLongGesture
(
gesture
:
UILongPressGestureRecognizer
) {
switch
(
gesture
.
state
) {
case
.
began
:
guard
let
selectedIndexPath
=
self
.
collectionView
.
indexPathForItem
(
at
:
gesture
.
location
(
in
:
self
.
collectionView
))
else
{
break
}
collectionView
.
beginInteractiveMovementForItem
(
at
:
selectedIndexPath
)
case
.
changed
:
collectionView
.
updateInteractiveMovementTargetPosition
(
gesture
.
location
(
in
:
gesture
.
view
!))
case
.
ended
:
self
.
collectionView
.
endInteractiveMovement
()
DispatchQueue
.
main
.
asyncAfter
(
deadline
: .
now
() + .
milliseconds
(
300
),
execute
: { [
weak
self
]
in
// 检测是否删除操作,是的话删除数据并调用 reloadData()
})
default
:
collectionView
.
cancelInteractiveMovement
()
}
}
|
加一个延迟处理就行
本文转自博客园农民伯伯的博客,原文链接:【Swift 4.0】iOS 11 UICollectionView 长按拖拽删除崩溃的问题,如需转载请自行联系原博主。