无法通过移动它们来重新排列 UICollectionView 中的单元格?

Posted

技术标签:

【中文标题】无法通过移动它们来重新排列 UICollectionView 中的单元格?【英文标题】:Unable to rearrange the cells in UICollectionView by moving them? 【发布时间】:2015-11-09 07:22:36 【问题描述】:

我有 UICollectionView,我在其上显示 custom 单元格。我试图通过长按手势来移动单元格,但它根本不起作用。

我已按照this 教程进行操作,但它对我不起作用。请告诉我该怎么做?

长按手势

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer


    NSLog(@"long press geture called");
    switch(gestureRecognizer.state)
    
        case UIGestureRecognizerStateBegan:
            p = [gestureRecognizer locationInView:self.collection_view];
          gesture_indexPath = [self.collection_view indexPathForItemAtPoint:p];
        [self.collection_view beginInteractiveMovementForItemAtIndexPath:gesture_indexPath];
            NSLog(@"state began called");

                     break;

        case UIGestureRecognizerStateChanged:

        //    collectionView.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
            [self.collection_view updateInteractiveMovementTargetPosition:[gestureRecognizer locationInView:[gestureRecognizer view]]];
            NSLog(@"state changed called");
        case UIGestureRecognizerStateEnded:
            [self.collection_view updateInteractiveMovementTargetPosition:p];
                  NSLog(@"state changed called");
        default:
            [self.collection_view cancelInteractiveMovement];
    

方法被覆盖

-(void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath

    NSLog(@"Move at index path called");

【问题讨论】:

【参考方案1】:

您在 switch-case 块中缺少 break; 语句。如果在每个 case 部分的末尾没有break;,则不会退出 switch-case 语句,而是执行下一行。

为了完整起见,这里是 Objective-C 中用于可重新排序的UICollectionView 的最低实现。

UICollectionView 实现重新排序 not 嵌入在 UICollectionViewController 内(可能改为在 UIViewController 内,但如果你喜欢的话,可能在 UICollectionViewCellUITableViewCell 内) 至少需要以下三个部分:

    viewDidLoad 内(或者,如果您在故事板中的UITableViewCellUICollectionViewCell 内嵌入UICollectionView,则此代码将在awakeFromNib 内),添加UILongPressGestureRecognizer 到你的UICollectionView 像这样:

    UILongPressGestureRecognizer *longGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)
    [self.yourCollectionView addGestureRecognizer:longGR];
    

    实现handleLongPress: 以响应您刚刚添加的UILongPressGestureRecognizer

    - (void)handleLongPress:(UILongPressGestureRecognizer *)gr   
        switch(gr.state)
            case UIGestureRecognizerStateBegan:
            
                NSIndexPath *selectedIndexPath = [self.yourCollectionView indexPathForItemAtPoint:[gr locationInView:self.yourCollectionView]];
                if(selectedIndexPath == nil) break;
                [self.yourCollectionView beginInteractiveMovementForItemAtIndexPath:selectedIndexPath];
                break;
            
            case UIGestureRecognizerStateChanged:
            
                [self.yourCollectionView updateInteractiveMovementTargetPosition:[gr locationInView:gr.view]];
                break;
            
            case UIGestureRecognizerStateEnded:
            
                [self.yourCollectionView endInteractiveMovement];
                break;
            
            default:
            
                [self.yourCollectionView cancelInteractiveMovement];
                break;
            
        
    
    

    最后,添加以下内容:

    - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
    
        //add your data source manipulation logic here
        //specifically, change the order of entries in the data source to match the new visual order of the cells.
        //even without anything inside this function, the cells will move visually if you build and run
    
    
    

....当您触摸、按住然后拖动时,单元格现在会神奇地移动!

(这一切都假设您已经实现了标准的 UICollectionView dataSourcedelegate 方法,并且 UICollectionView 已成功加载/显示在您的应用中。如果您需要有关 UICollectionView 基本设置的帮助,请查看 Warewolf 的 this post)。

【讨论】:

【参考方案2】:

你的 switch 语句失败了(将用 Swift 编写的博客文章翻译成 Objective-C 的危险之一)。每次对触摸位置发生变化的处理程序的调用都会执行 Changed: 情况下的每个语句,包括 cancelInteractiveMovement(另一方面,它可能应该是 endInteractiveMovement)。

【讨论】:

以上是关于无法通过移动它们来重新排列 UICollectionView 中的单元格?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过拖动在SwiftUI ZStack中重新排列视图

UICollectionViewCells 在重新排列后正在重置它们的大小

如何重新排列 UIActivityViewController 上的活动?

按住 windows phone 8 移动文本和图像

在 Angular Material CDK 拖放中,如何防止项目随着元素移动而自动重新排列?

通过重新排列数组来最大化数组绝对差的总和