正文

  功能

    用 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 长按拖拽删除崩溃的问题的更多相关文章

  1. Android实现RecyclerView侧滑删除和长按拖拽-ItemTouchHelper

    RecyclerView这个被誉为ListView和GirdView的替代品,它的用法在之前的一篇博文中就已经讲过了,今天我们就来实现RecyclerView的侧滑删除和长按拖拽功能,实现这两个功能我 ...

  2. Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮

    前言 之前写过屏蔽系统导航栏功能的文章,具体可看Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar 在某些特殊定制的版本中要求 ...

  3. [ActionScript 3.0] 动态绘制扇形实例(拖拽绘制)

    package { import flash.display.Shape; import flash.display.Sprite; import flash.events.MouseEvent; / ...

  4. vuejs2.0使用Sortable.js实现的拖拽功能

    简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...

  5. Android学习系列(11)--App列表之拖拽ListView(下)

    接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法.     在这个方法中我们主要是处理 ...

  6. vue2.0使用Sortable.js实现的拖拽功能

    简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jQuery ui中的sortable.js,只是在拖拽完成后,在update的回调函数中又重新排序了存放数据的数组.但 ...

  7. 使用TypeScript给Vue 3.0写一个指令实现组件拖拽

    最近在用vue3重构后台的一个功能.一个弹窗组件,弹出一个表单.然后点击提交. 早上运维突然跑过来问我,为啥弹窗挡住了下边的表格的数据,我添加的时候,都没法对照表格来看了.你必须给我解决一下. 我参考 ...

  8. vuejs2.0使用Sortable.js实现的拖拽功能( 转)

    文章目录   简介 实现效果 html主要代码 css代码 js代码 简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是 ...

  9. iOS 11 & iPhone X 适配资料集

    本文主要简单谈谈并收集一些关于 iOS 11 & iPhone X 的适配及设计指南. iPhone X 众所周知,iPhone X 屏幕与其他的 iPhone 设备均不同,苹果称 iPhon ...

随机推荐

  1. .Net语言 APP开发平台——Smobiler学习日志:在手机应用中开发蛛网表格

    最前面的话:Smobiler是一个在VS环境中使用.Net语言来开发APP的开发平台,也许比Xamarin更方便 样式一 一.目标样式 我们要实现上图中的效果,需要如下的操作: 1.从工具栏上的”Sm ...

  2. 第47章 授权端点(Authorize Endpoint) - Identity Server 4 中文文档(v1.0.0)

    授权端点可用于通过浏览器请求令牌或授权码.此过程通常涉及最终用户的身份验证和可选的同意. 注意 IdentityServer支持OpenID Connect和OAuth 2.0授权请求参数的子集.有关 ...

  3. Django 笔记分享

    Django是一个基于MVC构造的框架.但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model).模板(Template)和视图(Views), ...

  4. 一幅图,看懂中国CMMI

    以下数据由Fancier凡奉信息根据历年CMMI Institute公布的CMMI评估结果的汇总整理.数据跨度2008-2017年,包含对中国CMMI与全球CMMI的不同等级.版本的统计.

  5. Git:八、Git自定义:忽略特殊文件&配置别名

    1..gitignore配置文件 1)防止加入Git或输入git status时显示,需要让Git忽略的文件: 程序编译生成的非原代码的文件 存放密码的文件 2)配置文件:.gitignore Git ...

  6. Node.js模块导入导出

    这篇文章本来是想模块导入导出和事件循环一起写的,但是感觉一起写的话会太长了,所以就分开两篇文章写吧.下一篇会重点介绍一下js中的事件循环,js代码到底是以何种顺序去执行的呢?我相信你看懂了事件循环再去 ...

  7. PSP总结报告

    此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2556] 回顾0 alpha阶段前 团队名称:可以低头,但没必要 团队项 ...

  8. Oracle database link中查询会开启事务吗?

    关于oracle database link,使用database link相关的查询语句是否会开启事务呢?我们知道,在数据库中一个简单的SELECT查询语句不会产生事务(select for upd ...

  9. Tomcat开启SSL协议支持

    一.生成keyStore 要使用ssl connector,必须先创建一个keystore.他包含了服务器中被客户端用于验证服务器的数字证书.一旦客户端接受了这个证书,客户端就可以使用public k ...

  10. c/c++ linux 进程间通信系列5,使用信号量

    linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...