iOS怎么使用UICollectionView实现拖拽移动单元格
发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,这篇"iOS怎么使用UICollectionView实现拖拽移动单元格"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有
千家信息网最后更新 2024年11月28日iOS怎么使用UICollectionView实现拖拽移动单元格
这篇"iOS怎么使用UICollectionView实现拖拽移动单元格"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"iOS怎么使用UICollectionView实现拖拽移动单元格"文章吧。
一.介绍
iOS9提供API实现单元格排序呢功能,使用UICollectionView及其代理方法.iOS9之后有自带方法可以实现该效果,只需添加长按手势,实现手势方法和调用iOS9的API交换数据,iOS9之前需要自己写方法实现这效果,除了要添加长按手势,这里还需要利用截图替换原理,手动计算移动位置来处理视图交换和数据交换.
二.方法和步骤
1.创建工程项目和视图控制器,如下图
2.声明对象和设置代理和数据源代理
@interface ViewController ()@property (nonatomic, strong) NSMutableArray *dataArr;@property (nonatomic, strong) UICollectionView *collectionView;/**之前选中cell的NSIndexPath*/@property (nonatomic, strong) NSIndexPath *oldIndexPath;/**单元格的截图*/@property (nonatomic, strong) UIView *snapshotView;/**之前选中cell的NSIndexPath*/@property (nonatomic, strong) NSIndexPath *moveIndexPath; @end
3.初始化UICollectionView,并添加长按手势,在viewDidLoad中初始化
CGFloat SCREEN_WIDTH = self.view.frame.size.width; UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; flowLayout.itemSize = CGSizeMake((SCREEN_WIDTH-40.0)/3, (SCREEN_WIDTH-40.0)/3); UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 50.0, SCREEN_WIDTH, (SCREEN_WIDTH-40.0)/3+20.0) collectionViewLayout:flowLayout]; collectionView.dataSource = self; collectionView.delegate = self; collectionView.backgroundColor = [UIColor whiteColor]; [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"uicollectionviewcell"]; [self.view addSubview:self.collectionView = collectionView]; // 添加长按手势 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlelongGesture:)]; [collectionView addGestureRecognizer:longPress];
4.实例化数据源,(50个随机颜色,透明度0.8),在viewDidLoad中初始化
self.dataArr = [[NSMutableArray alloc] init];for (NSInteger index = 0; index < 50; index ++) { CGFloat hue = (arc4random()%256/256.0); //0.0 到 1.0 CGFloat saturation = (arc4random()8/256.0)+0.5; //0.5 到 1.0 CGFloat brightness = (arc4random()8/256.0)+0.5; //0.5 到 1.0 UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:0.5]; [self.dataArr addObject:color]; }
5.实现UICollectionView的UICollectionViewDataSource的两个必须实现的方法
#pragma mark - UICollectionViewDataSource- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return self.dataArr.count;} - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"uicollectionviewcell" forIndexPath:indexPath]; cell.backgroundColor = self.dataArr[indexPath.row]; return cell;}
6.重点来了,实现长按手势方法
#pragma mark - 长按手势- (void)handlelongGesture:(UILongPressGestureRecognizer *)longPress{ if ([[[UIDevice currentDevice] systemVersion] floatValue] < 9.0) { [self action:longPress]; } else { [self iOS9_Action:longPress]; }}
7.iOS9之后的实现
#pragma mark - iOS9 之后的方法- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath{ // 返回YES允许row移动 return YES;} - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ //取出移动row数据 id color = self.dataArr[sourceIndexPath.row]; //从数据源中移除该数据 [self.dataArr removeObject:color]; //将数据插入到数据源中的目标位置 [self.dataArr insertObject:color atIndex:destinationIndexPath.row];} - (void)iOS9_Action:(UILongPressGestureRecognizer *)longPress{ switch (longPress.state) { case UIGestureRecognizerStateBegan: { //手势开始 //判断手势落点位置是否在row上 NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[longPress locationInView:self.collectionView]]; if (indexPath == nil) { break; } UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath]; [self.view bringSubviewToFront:cell]; //iOS9方法 移动cell [self.collectionView beginInteractiveMovementForItemAtIndexPath:indexPath]; } break; case UIGestureRecognizerStateChanged: { // 手势改变 // iOS9方法 移动过程中随时更新cell位置 [self.collectionView updateInteractiveMovementTargetPosition:[longPress locationInView:self.collectionView]]; } break; case UIGestureRecognizerStateEnded: { // 手势结束 // iOS9方法 移动结束后关闭cell移动 [self.collectionView endInteractiveMovement]; } break; default: //手势其他状态 [self.collectionView cancelInteractiveMovement]; break; }}
8.iOS9之前的实现
#pragma mark - iOS9 之前的方法- (void)action:(UILongPressGestureRecognizer *)longPress{ switch (longPress.state) { case UIGestureRecognizerStateBegan: { // 手势开始 //判断手势落点位置是否在row上 NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[longPress locationInView:self.collectionView]]; self.oldIndexPath = indexPath; if (indexPath == nil) { break; } UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath]; // 使用系统的截图功能,得到cell的截图视图 UIView *snapshotView = [cell snapshotViewAfterScreenUpdates:NO]; snapshotView.frame = cell.frame; [self.view addSubview:self.snapshotView = snapshotView]; // 截图后隐藏当前cell cell.hidden = YES; CGPoint currentPoint = [longPress locationInView:self.collectionView]; [UIView animateWithDuration:0.25 animations:^{ snapshotView.transform = CGAffineTransformMakeScale(1.05, 1.05); snapshotView.center = currentPoint; }]; } break; case UIGestureRecognizerStateChanged: { // 手势改变 //当前手指位置 截图视图位置随着手指移动而移动 CGPoint currentPoint = [longPress locationInView:self.collectionView]; self.snapshotView.center = currentPoint; // 计算截图视图和哪个可见cell相交 for (UICollectionViewCell *cell in self.collectionView.visibleCells) { // 当前隐藏的cell就不需要交换了,直接continue if ([self.collectionView indexPathForCell:cell] == self.oldIndexPath) { continue; } // 计算中心距 CGFloat space = sqrtf(pow(self.snapshotView.center.x - cell.center.x, 2) + powf(self.snapshotView.center.y - cell.center.y, 2)); // 如果相交一半就移动 if (space <= self.snapshotView.bounds.size.width / 2) { self.moveIndexPath = [self.collectionView indexPathForCell:cell]; //移动 会调用willMoveToIndexPath方法更新数据源 [self.collectionView moveItemAtIndexPath:self.oldIndexPath toIndexPath:self.moveIndexPath]; //设置移动后的起始indexPath self.oldIndexPath = self.moveIndexPath; break; } } } break; default: { // 手势结束和其他状态 UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:self.oldIndexPath]; // 结束动画过程中停止交互,防止出问题 self.collectionView.userInteractionEnabled = NO; // 给截图视图一个动画移动到隐藏cell的新位置 [UIView animateWithDuration:0.25 animations:^{ self.snapshotView.center = cell.center; self.snapshotView.transform = CGAffineTransformMakeScale(1.0, 1.0); } completion:^(BOOL finished) { // 移除截图视图,显示隐藏的cell并开始交互 [self.snapshotView removeFromSuperview]; cell.hidden = NO; self.collectionView.userInteractionEnabled = YES; }]; } break; }}
三.iOS9之后添加的API如下
// Support for reordering- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0); // returns NO if reordering was prevented from beginning - otherwise YES- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition NS_AVAILABLE_IOS(9_0);- (void)endInteractiveMovement NS_AVAILABLE_IOS(9_0);- (void)cancelInteractiveMovement NS_AVAILABLE_IOS(9_0);
以上就是关于"iOS怎么使用UICollectionView实现拖拽移动单元格"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。
移动
手势
方法
数据
截图
位置
视图
单元
内容
数据源
代理
功能
动画
手指
效果
文章
步骤
状态
知识
篇文章
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
服务器设在西部延迟高
如何查数据库中的词语
sql数据库文件没有权限
益阳优质的数据库
关于网络安全的简答题目
网络安全可能导致的危害英语作文
电商网络安全技术
目前网络安全的概况
那个专科学校软件开发专业好
连接数据库需要下载什么
目录型数据库
lol安全连接到服务器
无备案服务器
搭建代码服务器
新一代网络技术发展趋势
互联网科技公司合同范本
2010年服务器
发电厂网络安全一二三区
我的世界中国服务器在哪下载
安仁科泰电脑软件开发
打印服务器 diy
锦州手机软件开发
网络安全设计原理
解放碑服务器是烟花区
河南虚拟现实软件开发
河南省大学生网络安全技术大赛
维普资讯全文期刊数据库
网络安全主题活动启动
清远数字软件开发报价表
使用缓存能缓解数据库热点吗