【Swift 4.0】iOS 11 UICollectionView 长按拖拽删除崩溃的问题

news/2024/7/24 10:48:05 标签: 移动开发, swift

 

正文

  功能

    用 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

  代码

swift;gutter:false;">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 又是异步操作,所以就报错了。

  解决

swift;gutter:true;">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()
    }
}

    加一个延迟处理就行

转载于:https://www.cnblogs.com/over140/p/7649827.html


http://www.niftyadmin.cn/n/1169964.html

相关文章

Codeforces 1140F Extending Set of Points (线段树分治+并查集)

这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc.h> using namespace std; typedef long long ll; const int maxn 3e5 50; typedef pair<int, int> pii; #define bug cout…

poj 2135 (基础费用流)

题意&#xff1a;从1到n再到1&#xff0c;每条边只能走一次&#xff0c;求最短距离。 建图&#xff1a;每条边只能走一次就是流量是1&#xff0c;添加源点与1相连&#xff0c;容量为2,费用为0&#xff0c;n与汇点相连容量为2,费用为0&#xff1b; 求增广路用SPFA最短路求&#…

C#实现水晶报表绑定数据并实现打印4-条形码

看了上几篇文章 加上自己的调试可以打出来了 大概记录下流程 1、在dataset中加入列code 类型System.Byte[] &#xff0c;并将此列拉至水晶报表某位置 2、安装BarcodeX并添加 barcodex.ocx 引用 3、新建 from 并拉一个 barcode过来 4、获取数据并赋值 barcodex.Caption “12345…

[USACO2004] Open提交作业(区间DP)

Description 贝西在哞哞大学选修了C门课&#xff0c;她要把这些课的作业交给老师&#xff0c;然后去车站和同学们一 起回家。老师们在办公室里&#xff0c;办公室要等他们下课后才开&#xff0c;第i门课的办公室在Ti时刻后开放。 所有的办公室都在一条走廊上&#xff0c;这条走…

JS中的BOM与DOM

BOM&#xff08;Broswer Object Model&#xff09; 定时器: 执行一次的定时器 var taskidwindow.setTimeout(function,ms); 关闭:window.clearTimeout(taskid); 执行无数次的定时器 var taskidwindow.setInteval(function,ms); 关闭:window.clearInteval(function,ms); 框窗…

map标签的详细使用参数

map标签必须成对出现&#xff0c;即 <map> ....</map> 同时map必须和area配合使用。 img标签里的usermap属性值必须与map标签里的id和name值完全一致 area标签&#xff1a;定义图片的点击区域 area 是单标签&#xff0c;不成对。 属性&#xff1a; accesskey 快捷键…

BarcodeX(ActiveX打印控件) v5.3.0.80 免费版使用

下载 地址 &#xff1a;https://www.xiazaila.com/soft/39537.html 转载&#xff1a;https://www.xiazaila.com/soft/39537.html BarcodeX是一款active打印控件&#xff0c;软件可以识别所有类型的条形码&#xff0c;识别之后就可以导出为位图、元文件和到剪贴板等&#xff0c…

IIS发布网站、发布webservice的重要说明

本文主要讲IIS发布网站、发布webservice的重要步骤、注意事项。 一、IIS发布网站、发布webservice 1.打开IIS管理器&#xff0c;如下图 2.在【网站】上点击右键&#xff0c;添加网站&#xff0c;设置如下图&#xff1a; 如果需要使用域名访问网站&#xff0c;则必须先购买域名并…