iOS开发笔记简友们的精华UICollectionView以及UITableView 列表

collectionView 拖拽单元格移动位置

2016-08-17  本文已影响4508人  Dannn_Y

iOS9新特性,collectionView的退拽

- (UICollectionView *)collectionView {
    if(_collectionView == nil) {
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
        flowLayout.itemSize = CGSizeMake(45, 45);
        flowLayout.minimumLineSpacing = 10;
        flowLayout.minimumInteritemSpacing = 10;
        flowLayout.sectionInset = UIEdgeInsetsMake(15, 15, 15, 15);
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight) collectionViewLayout:flowLayout];
        _collectionView.delegate = self;
        _collectionView.dataSource = self;
        _collectionView.backgroundColor = [UIColor whiteColor];
        [_collectionView registerClass:[MoveCollectionViewCell class] forCellWithReuseIdentifier:identity];
        
        UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressAction:)];
        [_collectionView addGestureRecognizer:longPressGesture];
        
    }
    return _collectionView;
}
    
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _data.count;
}
    
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    MoveCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identity forIndexPath:indexPath];
    cell.img = _data[indexPath.row];
    return cell;
}
- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath
- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition 
- (void)endInteractiveMovement
- (void)cancelInteractiveMovement;
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath 
参数 说明
collectionView 调用这个代理方法的 collection View
indexPath collectionView 中想要移动的 indexpath
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath
           toIndexPath:(NSIndexPath *)destinationIndexPath
参数 说明
collectionView 正在响应这个方法的collectionView
sourceIndexPath 原始移动的indexpath
destinationIndexPath 移动到目标位置的indexpath
- (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;
            }
            //开始移动
            [_collectionView beginInteractiveMovementForItemAtIndexPath:indexPath];
            break;
        case UIGestureRecognizerStateChanged:
        //移动过程中更新位置坐标
            [_collectionView updateInteractiveMovementTargetPosition:point];
            break;
        case UIGestureRecognizerStateEnded:
        //停止移动调用此方法
            [_collectionView endInteractiveMovement];
            break;
        default:
        //取消移动
            [_collectionView cancelInteractiveMovement];
            break;
    }
}
// 在开始移动时会调用此代理方法,
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
        //根据indexpath判断单元格是否可以移动,如果都可以移动,直接就返回YES ,不能移动的返回NO
        return YES;
}   

// 在移动结束的时候调用此代理方法
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath {
    /**
     *sourceIndexPath 原始数据 indexpath
     * destinationIndexPath 移动到目标数据的 indexPath
     */
    
    [_data removeObjectAtIndex:sourceIndexPath.row];
    UIImage *img = _data[sourceIndexPath.row]
    [_data insertObject:img atIndex:destinationIndexPath.row];
}

自己写collectionView拖拽的方法

- (void)longPressAction:(UILongPressGestureRecognizer *)longPress {
    //获取当前cell所对应的indexpath 
    MoveCollectionViewCell *cell = (MoveCollectionViewCell *)longPress.view;
    NSIndexPath *cellIndexpath = [_collectionView indexPathForCell:cell];
    
    //将此cell 移动到视图的前面
    [_collectionView bringSubviewToFront:cell];
    _isChange = NO;
    
    switch (longPress.state) {
        case UIGestureRecognizerStateBegan: {
        //使用数组将collectionView每个cell的 UICollectionViewLayoutAttributes 存储起来。
            [self.cellAttributesArray removeAllObjects];
            for (int i = 0; i < self.data.count; i++) {
                [self.cellAttributesArray addObject:[_collectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]]];
            }
        }
            break;
        case UIGestureRecognizerStateChanged: {
            //在移动过程中,使cell的中心与移动的位置相同。
            cell.center = [longPress locationInView:_collectionView];
            for (UICollectionViewLayoutAttributes *attributes in self.cellAttributesArray) {
            //判断移动cell的indexpath,是否和目的位置相同,如果相同isChange为YES,然后将数据源交换
                if (CGRectContainsPoint(attributes.frame, cell.center) && cellIndexpath != attributes.indexPath) {
                    _isChange = YES;
                    NSString *imgStr = self.data[cellIndexpath.row];
                    [self.data removeObjectAtIndex:cellIndexpath.row];
                    [self.data insertObject:imgStr atIndex:attributes.indexPath.row];
                    [self.collectionView moveItemAtIndexPath:cellIndexpath toIndexPath:attributes.indexPath];
                }
            }
            
        }
            break;
        case UIGestureRecognizerStateEnded: {
            //如果没有改变,直接返回原始位置
            if (!_isChange) {
                cell.center = [_collectionView layoutAttributesForItemAtIndexPath:cellIndexpath].center;
            }
        }
            break;
        default:
            break;
    }
}

不使用iOS9的代理方法,实现拖拽移动也很简单,可以试试。
代码已经放到github仓库请点击这里 项目链接 查看

上一篇下一篇

猜你喜欢

热点阅读