iOS调整collectionViewCell顺序

效果图

请添加图片描述

原理

就是设置collectionView调整顺序的代理方法,这里要注意一点
调整过代理方法之后,一定要修改数据源,否则导致错乱。
还有就是在collectionView上面添加一个长按手势,在长按手势的不同阶段,调用collectionView 调整顺序的系统方法 beginInteractiveMovementForItemAtIndexPath
等等

代码

//
//  ViewController.m
//  LBEditCollectionCellOrder
//
//  Created by mac on 2024/6/10.
//

#import "ViewController.h"
#import "LBOrderCell.h"

@interface ViewController () <UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView *collectionView;

@property (nonatomic, strong) UILongPressGestureRecognizer *longPressRecognizer;

@property (nonatomic, strong) NSMutableArray *dataArray;

@property (nonatomic, assign) BOOL inDrag;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.collectionView];
    [self.collectionView reloadData];
    [self.collectionView addGestureRecognizer:self.longPressRecognizer];
    // Do any additional setup after loading the view.
}

#pragma mark - 手势拖拽

- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
{
    //最后一个不能拖拽
    return self.dataArray.count > indexPath.item;
}


- (NSIndexPath *)collectionView:(UICollectionView *)collectionView targetIndexPathForMoveOfItemFromOriginalIndexPath:(NSIndexPath *)originalIndexPath atCurrentIndexPath:(NSIndexPath *)currentIndexPath toProposedIndexPath:(NSIndexPath *)proposedIndexPath
{
    if ([self collectionView:collectionView canMoveItemAtIndexPath:proposedIndexPath]) {
        return proposedIndexPath;
    }
    return originalIndexPath;
}

- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    NSString *title = [self.dataArray objectAtIndex:sourceIndexPath.item];
    if (!title) {
        return;
    }
    
    NSInteger targetIdx = destinationIndexPath.item;
    NSLog(@"修改之前的数量%ld",self.dataArray.count);
    [self.dataArray removeObject:title];
    NSLog(@"这里的%@", title);
    NSLog(@"这是否包含%d", [self.dataArray containsObject:title]);
    [self.dataArray insertObject:title atIndex:targetIdx];
    NSLog(@"修改之后的数量%ld", self.dataArray.count);
}

#pragma mark - UICollectionViewDelegate, UICollectionViewDataSource

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.dataArray.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    LBOrderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([LBOrderCell class]) forIndexPath:indexPath];
    [cell updateWithText:self.dataArray[indexPath.item]];
    return cell;
}

#pragma mark - action

- (void)longPressRecognizer:(UILongPressGestureRecognizer *)gestureRecognizer
{
    CGPoint point = [gestureRecognizer locationInView:self.collectionView];
    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan: {
            NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:point];
            if (selectedIndexPath) {
                [self.collectionView beginInteractiveMovementForItemAtIndexPath:selectedIndexPath];
            }
            break;
        }
        case UIGestureRecognizerStateChanged: {
            [self.collectionView updateInteractiveMovementTargetPosition:point];
            break;;
        }
        case UIGestureRecognizerStateEnded: {
            [self.collectionView endInteractiveMovement];
            break;
        }
        default:
        {
            [self.collectionView cancelInteractiveMovement];
        }
            break;
    }
}

#pragma mark - lazy load

- (UICollectionView *)collectionView
{
    if (!_collectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        CGFloat w = (CGRectGetWidth(self.view.bounds) - 2 * 8 - 2 * 20.5)/3;
        CGFloat space = 8;
        layout.itemSize = CGSizeMake(w, w);
        layout.minimumLineSpacing = space;
        layout.sectionInset = UIEdgeInsetsMake(0, 16, 0, 16);
        self.view.clipsToBounds = YES;
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, CGRectGetWidth(self.view.bounds), 350) collectionViewLayout:layout];
        [_collectionView registerClass:[LBOrderCell class] forCellWithReuseIdentifier:NSStringFromClass([LBOrderCell class])];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.backgroundColor = [UIColor cyanColor];
    }
    return _collectionView;
}

- (UILongPressGestureRecognizer *)longPressRecognizer
{
    if (!_longPressRecognizer) {
        _longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressRecognizer:)];
        _longPressRecognizer.minimumPressDuration = 0.3;
    }
    return _longPressRecognizer;
}

- (NSMutableArray *)dataArray
{
    if (!_dataArray) {
        NSArray *array = @[@"1", @"2", @"3", @"4", @"5", @"6",@"7", @"8", @"9", @"10", @"11", @"12"];
        _dataArray = [NSMutableArray array];
        [_dataArray addObjectsFromArray:array];
    }
    return _dataArray;
}

@end

链接: link
如果对您有帮助,请给一个star

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/696502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode1318或运算的最小翻转次数

题目描述 给你三个正整数 a、b 和 c。你可以对 a 和 b 的二进制表示进行位翻转操作&#xff0c;返回能够使按位或运算 a OR b c 成立的最小翻转次数。「位翻转操作」是指将一个数的二进制表示任何单个位上的 1 变成 0 或者 0 变成 1 。 解析 这一题就按位依次比较就行了。取这…

大话设计模式解读02-策略模式

本篇文章&#xff0c;来解读《大话设计模式》的第2章——策略模式。并通过Qt和C代码实现实例代码的功能。 1 策略模式 策略模式作为一种软件设计模式&#xff0c;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式的特点&#…

【设计模式】创建型设计模式之 工厂模式

一、介绍 工厂模式可以分为 3 个小类 简单工厂模式工厂方法模式抽象工厂模式 工厂模式的工厂类&#xff0c;并不一定以 Factory 结尾&#xff0c;例如 DataFormat、Calender 他们都是工厂类&#xff0c;通过静态方法来创建实例。 除此之外&#xff0c;创建对象的方法名称一…

利用医学Twitter进行病理图像分析的视觉-语言基础模型| 文献速递-视觉通用模型与疾病诊断

Title 题目 A visual–language foundation model for pathology image analysis using medical Twitter 利用医学Twitter进行病理图像分析的视觉-语言基础模型 01 文献速递介绍 缺乏公开可用的医学图像标注是计算研究和教育创新的一个重要障碍。同时&#xff0c;许多医生…

Linux - 信号概念 信号产生

Linux - 信号概念 & 信号产生 信号概念信号产生软件信号killraiseabortalarm 硬件信号键盘产生信号硬件中断 信号概念 信号是进程之间事件异步通知的一种方式 在Linux命令行中&#xff0c;我们可以通过ctrl c来终止一个前台运行的进程&#xff0c;其实这就是一个发送信号的…

Java面试_数据库篇_优化,事务,Mysql

Java面试_数据库篇_优化,事务,Mysql 优化如何定位慢查询方案一: 开源工具方案二: Mysql自带慢日志 如何分析慢SQL语句索引介绍索引聚簇索引和非聚簇索引&#xff0c;回表查询覆盖索引&#xff0c;超大分页优化索引创建的原则索引失效 谈谈sql优化的经验 事务事务特性隔离级别un…

vue-2 组件传值

组件关系分类 父子关系非父子关系 父子通信流程 父组件通过props将数据传递给子组件 给子组件以添加属性的方式传值子组件内部通过 props 接收模板中直接使用 props 接收的值 父组件 Parent.vue <template><div class"parent" style"border: 3px s…

力扣 T62 不同路径

题目 连接 思路 思路1 &#xff1a; BFS爆搜 class Solution { public:queue<pair<int,int>>q;int uniquePaths(int m, int n) {q.push({1,1}); // 起始位置vector<pair<int, int>> actions;actions.push_back({0, 1}); // 向下actions.push_bac…

论文中eps格式图片制作

在提交论文终稿时&#xff0c;有时需要提交论文中图片的eps格式&#xff0c;这里记录一下eps格式图片制作的过程&#xff0c;方便以后查阅。 论文中eps格式图片制作 PPT绘制的图片转换为eps格式使用代码生成的图片Latex中显示的图片大小跟Ai中设定画板的大小不一致 PPT绘制的图…

ABB机械人模型下载

可以下载不同格式的 https://new.abb.com/products/robotics/zh/robots/articulated-robots/irb-6700 step的打开各部件是分开的&#xff0c;没有装配在一起&#xff0c;打开看单个零件时&#xff0c;我们会发现其各零件是有装配的定位关系的。 新建一个装配环境&#xff0c;点…

ctfshow-web入门-命令执行(web53-web55)

目录 1、web53 2、web54 3、web55 1、web53 这里的代码有点不一样&#xff0c;说一下这两种的区别&#xff1a; &#xff08;1&#xff09;直接执行 system($c); system($c);这种方式会直接执行命令 $c 并将命令的输出直接发送到标准输出&#xff08;通常是浏览器&#xff…

基于机器学习和深度学习的NASA涡扇发动机剩余使用寿命预测(C-MAPSS数据集,Python代码,ipynb 文件)

以美国航空航天局提供的航空涡扇发动机退化数据集为研究对象&#xff0c;该数据集包含多台发动机从启动到失效期间多个运行周期的多源传感器时序状态监测数据&#xff0c;它们共同表征了发动机的性能退化情况。为减小计算成本&#xff0c;需要对原始多源传感器监测数据进行数据…

软件测试--Mysql快速入门

文章目录 软件测试-mysql快速入门sql主要划分mysql常用的数据类型sql基本操作常用字段的约束&#xff1a;连接查询mysql内置函数存储过程视图事务索引 软件测试-mysql快速入门 sql主要划分 sql语言主要分为&#xff1a; DQL&#xff1a;数据查询语言&#xff0c;用于对数据进…

SpringBoot中实现一个通用Excel导出功能

SpringBoot中实现一个通用Excel导出功能 文章目录 SpringBoot中实现一个通用Excel导出功能这个导出功能的特色看效果代码解析1、依赖2、Excel 入参(ExcelExportRequest)3、Excel 出参(ExcelExportResponse)4、ExcelExportField5、ExcelExportUtils 工具类6、ExcelHead 头部…

鸿蒙开发接口安全:【@ohos.userIAM.userAuth (用户认证)】

用户认证 说明&#xff1a; 本模块首批接口从API version 6开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import userIAM_userAuth from ohos.userIAM.userAuth;完整示例 // API version 6 import userIAM_userAuth from ohos.use…

AI全栈工程师的新舞台:Coze(扣子)

前言 在当前科技飞速发展的背景下&#xff0c;Coze作为一款引领潮流的AI应用平台&#xff0c;正以破竹之势重塑着我们对于智能应用的认知。Coze不仅仅是一个工具&#xff0c;它是一个集合了前沿AI技术、高效开发环境与创意无限的应用生态于一体的创新平台&#xff0c;旨在让每…

RabbitMQ-工作模式(Topics模式RPC模式Publisher Confirms模式)

文章目录 Topics模式topic代码示例 RPC模式客户端界面回调队列关联ID总结RPC代码示例 Publisher Confirms模式概述在通道上启用发布者确认单独发布消息批量发布消息异步处理发布者确认总结总体代码示例 更多相关内容可查看 Topics模式 在Topics中&#xff0c;发送的消息不能具…

QT 信号和槽 信号关联到信号示例 信号除了可以绑定槽以外,信号还可以绑定信号

信号除了可以关联到槽函数&#xff0c;还可以关联到类型匹配的信号&#xff0c;实现信号的接力触发。上个示例中因为 clicked 信号没有参数&#xff0c;而 SendMsg 信号有参数&#xff0c;所以不方便直接关联。本小节示范一个信号到信号的关联&#xff0c;将按钮的 clicked 信号…

---java 抽象类 和 接口---

抽象类 再面向对对象的语言中&#xff0c;所以的对象都是通过类来描述的&#xff0c;但如果这个类无法准确的描述对象的 话&#xff0c;那么就可以把这个类设置为抽象类。 实例 这里用到abstract修饰&#xff0c;表示这个类或方法是抽象方法 因为会重写motifs里的show方法…

【已解决】FileNotFoundError: [Errno 3] No such file or directory: ‘xxx‘

&#x1f60e; 作者介绍&#xff1a;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff0c;视频号&#xff1a;AI-行者Sun &#x1f388; 本文专栏&#xff1a;本文收录于《AI实战中的各种bug…