美文网首页
UITableViewCell单Section及多Section

UITableViewCell单Section及多Section

作者: 人生若只如初见丶_a4e8 | 来源:发表于2022-03-03 16:03 被阅读0次

    前言

    最近项目中需要拖动UITableViewCell进行排序,基于系统的方法只能进入编辑模式触发,且没有Section间的控制方法,UI也有局限性,所以参考网上做法实现如下效果:


    image.png

    以实现不同的Section间单独处理。

    首先

    cell的操作图片上添加长按手势,根据state的值进行操作

    - (void)dragCell:(UITableViewCell *)cell recognizer:(UILongPressGestureRecognizer *)longPress {
        UIGestureRecognizerState state = longPress.state;
        switch (state) {
            case UIGestureRecognizerStateBegan: {
                NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
                if (indexPath) {
                    self.sourceIndexPath = indexPath;
                    self.snapshot = [self customSnapshoFromView:cell];
                    __block CGPoint center = cell.center;
                    self.snapshot.center = center;
                    self.snapshot.alpha = 0.0;
                    [self.tableView addSubview:self.snapshot];
    
                    [UIView animateWithDuration:0.25 animations:^{
                        self.snapshot.center = center;
                        self.snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
                        self.snapshot.alpha = 0.98;
                        cell.alpha = 0.0f;
                    } completion:^(BOOL finished) {
                        cell.hidden = YES;
                    }];
                }
    
                break;
            }
                
            case UIGestureRecognizerStateChanged: {
                CGPoint location = [longPress locationOfTouch:0 inView:self.tableView];
                CGPoint center = self.snapshot.center;
                center.y = location.y;
                self.snapshot.center = center;
                NSIndexPath *changedIndexPath = [self.tableView indexPathForRowAtPoint:location];
    
                // 是否位置变动
                if (changedIndexPath && ![changedIndexPath isEqual:self.sourceIndexPath]) {
                    if (changedIndexPath.section != self.sourceIndexPath.section) {
                        return;
                    }
                    // 要拖动的数据
                    NSArray *sectionArry = self.getAdapterArry[self.sourceIndexPath.section];
                    // 移动数据交换
                    NSMutableArray *sourceSectionArry = sectionArry.mutableCopy;
                    [sourceSectionArry exchangeObjectAtIndex:changedIndexPath.row withObjectAtIndex:self.sourceIndexPath.row];
                    // 更新数据源
                    [self.getAdapterArry replaceObjectAtIndex:self.sourceIndexPath.section withObject:sourceSectionArry];
                    [[YSCommonDataManager shareManager] addtoKLineIndexStyleSet:self.getAdapterArry];
                    
                    [self.tableView moveRowAtIndexPath:self.sourceIndexPath toIndexPath:changedIndexPath];
                    self.sourceIndexPath = changedIndexPath;
                }
                
                break;
            }
            // 最后就是默认(拖动完成或者未拖动)
            default: {
                // Clean up.
                UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.sourceIndexPath];
                
                [UIView animateWithDuration:0.25 animations:^{
                    self.snapshot.center = cell.center;
                    self.snapshot.transform = CGAffineTransformIdentity;
                    self.snapshot.alpha = 0.0;
                    cell.alpha = 1.0f;
                } completion:^(BOOL finished) {
                    cell.hidden = NO;
                    [self.snapshot removeFromSuperview];
                    self.snapshot = nil;
                }];
                self.sourceIndexPath = nil;
                
                break;
            }
        }
    }
    

    接着

    为了能实现悬浮的效果,需要创建一个快照视图。
    @property (nonatomic, strong) UIView *snapshot;

    - (UIView *)customSnapshoFromView:(UIView *)inputView {
        UIView *snapshot = nil;
        snapshot = [inputView snapshotViewAfterScreenUpdates:YES];
        snapshot.layer.masksToBounds = NO;
        snapshot.layer.cornerRadius = 0.0;
        snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
        snapshot.layer.shadowRadius = 5.0;
        snapshot.layer.shadowOpacity = 0.4;
        
        return snapshot;
    }
    
    • UIGestureRecognizerStateBegan时,获取被移动cell的起始位置sourceIndexPath,将snapshot快照视图加入到tableView上,隐藏原来的cell
    • UIGestureRecognizerStateChanged时,获取到按压手势的偏移位置,调整snapshot的位置,得到快照被拖移到的新位置changedIndexPath,后根据
      // 是否位置变动
      if (changedIndexPath && ![changedIndexPath isEqual:self.sourceIndexPath]) { if (changedIndexPath.section != self.sourceIndexPath.section) { return; } }
      来隔断不同section间的拖动。以及进行数据源交换,cell交换,更新sourceIndexPath等操作。
    • 最后在default状态,根据最新的sourceIndexPath来完成拖动完成或者失败的动画效果。

    至此

    完成了单Section及多Section的Cell手势拖动。

    参考文章和源码:
    iOS UITableView可以拖动排序的Cell

    相关文章

      网友评论

          本文标题:UITableViewCell单Section及多Section

          本文链接:https://www.haomeiwen.com/subject/hpfurrtx.html