iOS 学习 - 20.UICollectionView 移动 Item ,类似背包
有100个 item,数据源只有20个,只能在 20 个之间移动,防止 item 复用,出现 bug
方法一:苹果自带
//UICollectionViewDataSource
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath; - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;
方法二:
1.获取要拖拽的 Item
2.使用系统自带方法截图,隐藏当前 Item
3.交换位置、数据位置
#pragma mark -- 手势开始
- (void)xwp_gestureBegan:(UILongPressGestureRecognizer *)longPressGesture{
CGFloat y = [longPressGesture locationInView:longPressGesture.view].y;
//超过数据源的 item 不执行
if (y <= [self row]) {
//获取手指所在的cell
_originalIndexPath = [self indexPathForItemAtPoint:[longPressGesture locationOfTouch:0 inView:longPressGesture.view]];
UICollectionViewCell *cell = [self cellForItemAtIndexPath:_originalIndexPath];
//使用系统自带方法截图
UIView *tempMoveCell = [cell snapshotViewAfterScreenUpdates:NO];
//隐藏当前 Item
cell.hidden = YES;
_tempMoveCell = tempMoveCell;
_tempMoveCell.frame = cell.frame;
[self addSubview:_tempMoveCell];
//开启边缘滚动定时器
[self xwp_setEdgeTimer];
//开启抖动
if (_shakeWhenMoveing && !_editing) {
[self xwp_shakeAllCell];
[self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
_lastPoint = [longPressGesture locationOfTouch:0 inView:longPressGesture.view];
//通知代理
if ([self.delegate respondsToSelector:@selector(dragCellCollectionView:cellWillBeginMoveAtIndexPath:)]) {
[self.delegate dragCellCollectionView:self cellWillBeginMoveAtIndexPath:_originalIndexPath];
}
}
}
#pragma mark -- 手势抖动
- (void)xwp_gestureChange:(UILongPressGestureRecognizer *)longPressGesture{
//获取点击位置 y 值
CGFloat y = [longPressGesture locationInView:longPressGesture.view].y;
//限制手势范围 y 值
if (y <= [self row]) {
NSLog(@"-----%f",y);
//通知代理
if ([self.delegate respondsToSelector:@selector(dragCellCollectionViewCellisMoving:)]) {
[self.delegate dragCellCollectionViewCellisMoving:self];
}
CGFloat tranX = [longPressGesture locationOfTouch:0 inView:longPressGesture.view].x - _lastPoint.x;
CGFloat tranY = [longPressGesture locationOfTouch:0 inView:longPressGesture.view].y - _lastPoint.y;
_tempMoveCell.center = CGPointApplyAffineTransform(_tempMoveCell.center, CGAffineTransformMakeTranslation(tranX, tranY));
_lastPoint = [longPressGesture locationOfTouch:0 inView:longPressGesture.view];
[self xwp_moveCell];
}else{
//如果超过范围,就把当前拖动的 item y 值设为数据源的底部
_tempMoveCell.frame = CGRectMake(_tempMoveCell.frame.origin.x, [self row], _tempMoveCell.frame.size.width, _tempMoveCell.frame.size.height);
}
}
#pragma mark -- 手势取消或者结束
- (void)xwp_gestureEndOrCancle:(UILongPressGestureRecognizer *)longPressGesture{
UICollectionViewCell *cell = [self cellForItemAtIndexPath:_originalIndexPath];
self.userInteractionEnabled = NO;
[self xwp_stopEdgeTimer];
//通知代理
if ([self.delegate respondsToSelector:@selector(dragCellCollectionViewCellEndMoving:)]) {
[self.delegate dragCellCollectionViewCellEndMoving:self];
}
//一个小动画
[UIView animateWithDuration:0.25 animations:^{
_tempMoveCell.center = cell.center;
} completion:^(BOOL finished) {
[self xwp_stopShakeAllCell];
[_tempMoveCell removeFromSuperview];
cell.hidden = NO;
self.userInteractionEnabled = YES;
}];
}
完整 demo,放在 githud 上,点我
CocoaChina 上在这里