项目开发中遇到拖拽功能的需求,具体要求是在编辑状态下,首页底部菜单项可以拖动位置,便于位置切换。遇到问题后的初步想法是添加拖拽手势,拖拽到某个位置,判断拖拽cell的中心点是否在另一个cell内,这样处理比较复杂,需要自己计算坐标。后经一同事推荐,找到了一个更简单的解决方案,代码如下。
//1、给cell添加长按手势,在编辑状态下可用,非编辑状态下不可用
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CCNewMoreMenuCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CCNewMoreMenuCellIdentifier forIndexPath:indexPath];
CCHighSeasPoolManager *seas=[CCHighSeasPoolManager sharedManager];
//添加长按手势
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
[cell addGestureRecognizer:longPressGesture];
if (seas.isEdit) {
[cell.btnDelete setHidden:NO];
[cell.imageDelete setHidden:NO];
[cell.btnMenu setHidden:YES];
longPressGesture.cancelsTouchesInView=YES;
//编辑状态开启手势
longPressGesture.enabled=YES;
}else{
[cell.btnDelete setHidden:YES];
[cell.imageDelete setHidden:YES];
[cell.btnMenu setHidden:NO];
//非编辑状态禁用手势
longPressGesture.enabled=NO;
}
[cell.btnMenu addTarget:self action:@selector(btnMenuAction:) forControlEvents:UIControlEventTouchDown];
cell.btnMenu.btnRow=indexPath.item;
[cell.btnDelete addTarget:self action:@selector(btnDeleteAction:) forControlEvents:UIControlEventTouchDown];
cell.btnDelete.btnRow=indexPath.item;
CCMoreListModel *model = [seas.dataList objectAtIndex:indexPath.item];
cell.headerModel=model;
return cell;
}
//2、添加长按手势处理方法
- (void)longPressAction:(UILongPressGestureRecognizer *)longPress {
//获取此次点击的坐标,根据坐标获取cell对应的indexPath
CGPoint point = [longPress locationInView:_collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:point];
//根据长按手势的状态进行处理。
switch (longPress.state) {
case UIGestureRecognizerStateBegan:
//当没有点击到cell的时候不进行处理
if (!indexPath) {
break;
}
//开始移动
[self.collectionView beginInteractiveMovementForItemAtIndexPath:indexPath];
break;
case UIGestureRecognizerStateChanged:
//移动过程中更新位置坐标
[self.collectionView updateInteractiveMovementTargetPosition:point];
break;
case UIGestureRecognizerStateEnded:
//停止移动调用此方法
[self.collectionView endInteractiveMovement];
break;
default:
//取消移动
[self.collectionView cancelInteractiveMovement];
break;
}
}
//3、监测可移动状态
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
//根据indexpath判断单元格是否可以移动,如果都可以移动,直接就返回YES ,不能移动的返回NO
return YES;
}
//4、通过系统的移动代理,交换拖动菜单项
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath{
CCHighSeasPoolManager *seas=[CCHighSeasPoolManager sharedManager];
[seas.dataList exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
}