collectionVIew 的拖拽,主要是利用手势,进行操作,就是 UILongPressGestureRecognizer,实现UICollectionVIewCell的手势,且借助于,
[locationOfTouch:0 inView:longPgr.view]
得到长按手势的CGPoint点,同时借助于
[self indexPathForItemAtPoint: ] 获取到某一点在cell上,是在那个indexPath
根据手势的不同状态去做相应的操作
-(void)longPrgEvent:(UILongPressGestureRecognizer*)longPger{ if (longPger.state == UIGestureRecognizerStateBegan) { self.isDeleteItem = NO; [self gestureRecognizerBegan:longPger]; }else if (longPger.state == UIGestureRecognizerStateChanged){ if (self.originalIndexPath.section != 0) { return; } [self gestureRecognizerChange:longPger]; [self moveCell]; }else if (longPger.state == UIGestureRecognizerStateCancelled || longPger.state == UIGestureRecognizerStateEnded){ [self handelItemInSpace]; if (!self.isDeleteItem) { [self gestureRecognizerCancelOrEnd:longPger]; } } }
#当手势刚开始拖动的时候 - (void)gestureRecognizerBegan:(UILongPressGestureRecognizer *)longPgr{ self.originalIndexPath = [self indexPathForItemAtPoint:[longPgr locationOfTouch:0 inView:longPgr.view]]; SFCollectionViewCell * cell = (SFCollectionViewCell*)[self cellForItemAtIndexPath:self.originalIndexPath]; UIView * tempMoveCell = [cell snapshotViewAfterScreenUpdates:NO]; //获取一个截屏试图,用于试图的移动, self.dragCell = cell; cell.hidden = YES; self.tempMoveCell = tempMoveCell; self.tempMoveCell.frame = cell.frame; [UIView animateWithDuration:0.25 animations:^{ self.tempMoveCell.alpha = 0.8; self.tempMoveCell.transform = CGAffineTransformMakeScale(1.15, 1.15); }]; [self addSubview:self.tempMoveCell]; self.lastPoint = [longPgr locationOfTouch:0 inView:self]; }
#prarm 当拖拽手势处于变化状态时候,让刚开始获取到的cell截图,做一些移动动画 利用到矩阵变换 // CGAffineTransformMakeTranslation(x,y) 矩阵变换,位移 // CGAffineTransformMakeRotation(M_PI); 矩阵变换,旋转 // CGAffineTransformMakeScale(2, 2); 矩阵变换,缩放 // CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t) 某点通过矩阵变换之后的点 - (void)gestureRecognizerChange:(UILongPressGestureRecognizer *)longPgr{ CGFloat tranX = [longPgr locationOfTouch:0 inView:longPgr.view].x - self.lastPoint.x; CGFloat tranY = [longPgr locationOfTouch:0 inView:longPgr.view].y - self.lastPoint.y; // NSLog(@"start %@",NSStringFromCGPoint(self.tempMoveCell.center)); self.tempMoveCell.center = CGPointApplyAffineTransform(self.tempMoveCell.center, CGAffineTransformMakeTranslation(tranX, tranY)); // NSLog(@"end %@",NSStringFromCGPoint(self.tempMoveCell.center)); self.lastPoint = [longPgr locationOfTouch:0 inView:longPgr.view]; // NSLog(@"tranX:%f-tranY:%f--%@",tranX,tranY,NSStringFromCGPoint(self.lastPoint)); // CGAffineTransformMakeTranslation(x,y) --相对平移 将view(泛指)移动到相对于“屏幕的左上角” }
当然当手势处于移动状态下,cell整体需要根据移动的截图的位置,判断出,可能移动到的cell位置,然后做出动画
核心知识点 [self moveItemAtIndexPath:self.originalIndexPath toIndexPath:self.moveIndexPath];
- (void)moveCell{ for (SFCollectionViewCell * cell in self.visibleCells) { if ([self indexPathForCell:cell] == self.originalIndexPath) { continue; } //计算中心距离 CGFloat spaceingX = fabs(self.tempMoveCell.center.x - cell.center.x); CGFloat spaceingY = fabs(self.tempMoveCell.center.y - cell.center.y); if (spaceingX <= self.tempMoveCell.bounds.size.width/2.0f && spaceingY <= self.tempMoveCell.bounds.size.height/2.0f) { self.moveIndexPath = [self indexPathForCell:cell]; if (self.moveIndexPath.section != 0) { return; } //更新数据源 [self updateDataSource]; //移动 [self moveItemAtIndexPath:self.originalIndexPath toIndexPath:self.moveIndexPath]; self.originalIndexPath = self.moveIndexPath; } } }
那么剩下就是更新数据源,将拖拽更换位置更换对应的数据,跳换位置,根据移动位置,中拿到的。originalIndexPath:最初位置 moveIndexPath : 移动到的位置,就行数据更新
Demo地址
https://github.com/wangsongfeng/CLYTabbarController-test.git