【Swift 4.0】iOS 11 UICollectionView 长按拖拽删除崩溃的问题
正文
功能
用 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 又是异步操作,所以就报错了。
解决
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 长按拖拽删除崩溃的问题的更多相关文章
- Android实现RecyclerView侧滑删除和长按拖拽-ItemTouchHelper
RecyclerView这个被誉为ListView和GirdView的替代品,它的用法在之前的一篇博文中就已经讲过了,今天我们就来实现RecyclerView的侧滑删除和长按拖拽功能,实现这两个功能我 ...
- Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
前言 之前写过屏蔽系统导航栏功能的文章,具体可看Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar 在某些特殊定制的版本中要求 ...
- [ActionScript 3.0] 动态绘制扇形实例(拖拽绘制)
package { import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; / ...
- vuejs2.0使用Sortable.js实现的拖拽功能
简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...
- Android学习系列(11)--App列表之拖拽ListView(下)
接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法. 在这个方法中我们主要是处理 ...
- vue2.0使用Sortable.js实现的拖拽功能
简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jQuery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...
- 使用TypeScript给Vue 3.0写一个指令实现组件拖拽
最近在用vue3重构后台的一个功能.一个弹窗组件,弹出一个表单.然后点击提交. 早上运维突然跑过来问我,为啥弹窗挡住了下边的表格的数据,我添加的时候,都没法对照表格来看了.你必须给我解决一下. 我参考 ...
- vuejs2.0使用Sortable.js实现的拖拽功能( 转)
文章目录 简介 实现效果 html主要代码 css代码 js代码 简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是 ...
- iOS 11 & iPhone X 适配资料集
本文主要简单谈谈并收集一些关于 iOS 11 & iPhone X 的适配及设计指南. iPhone X 众所周知,iPhone X 屏幕与其他的 iPhone 设备均不同,苹果称 iPhon ...
随机推荐
- #1 爬虫:豆瓣图书TOP250 「requests、BeautifulSoup」
一.项目背景 随着时代的发展,国人对于阅读的需求也是日益增长,既然要阅读,就要读好书,什么是好书呢?本项目选择以豆瓣图书网站为对象,统计其排行榜的前250本书籍. 二.项目介绍 本项目使用Python ...
- shell32.dll 控制网络
//禁用 SetNetworkAdapter(False) //启用 SetNetworkAdapter(True) //添加引用system32/shell32.dll private static ...
- windows server 2012/2016 设置多用户远程桌面(转载)
方案一: 该方案只能满足两个人同时远程. 方案二: https://blog.csdn.net/flyingshuai/article/details/77869279
- Java开发笔记(三十)大小数BigDecimal
前面介绍的BigInteger只能表达任意整数,但不能表达小数,要想表达任意小数,还需专门的大小数类型BigDecimal.如果说设计BigInteger的目的是替代int和long类型,那么设计Bi ...
- MySQL优化COUNT()查询
COUNT()聚合函数,以及如何优化使用了该函数的查询,很可能是最容易被人们误解的知识点之一 COUNT()的作用 COUNT()是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量 统计行数 ...
- SAP MM 实施项目里Open PO 迁移思路探讨
SAP MM 实施项目里Open PO 迁移思路探讨 .序言. SAP项目上线前夕,除了静态主数据需要导入以外,可能还有一些动态数据,比如open的采购订单,open的销售订单等单据也要迁移到SA ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
- C#中Skip和Take的用法
Skip()和Take()方法都是IEnumerable<T> 接口的扩展方法,包括C#中的所有Collections类,如ArrayList,Queue,Stack等等,还有数组和字符串 ...
- SQL Server数据库————连接查询和分组查询
SQL Server数据库————连接查询和分组查询 分组查询 select 列from <表名> where …… group by 列 注意:跟order by一样group ...
- c/c++ linux 进程间通信系列5,使用信号量
linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...