【问题标题】:Exchange position of cells by gesture通过手势交换单元格的位置
【发布时间】:2015-12-28 10:15:03
【问题描述】:

我有UICollectionView,其中有一个原型单元和UIImageView。我在UICollectionView 中显示随机图像。

现在我想通过将UIImageView 滑动到单元格附近来交换它的位置。我尝试过滑动手势和长按手势。下面给出了我已经完成的代码:

- (IBAction)LongPress:(UILongPressGestureRecognizer *)sender
{
    if (sender.state != UIGestureRecognizerStateEnded) 
    {
        return;
    }
    CGPoint p = [sender locationInView:self.collectionView];

    NSIndexPath *indexPath = [self.coll_out indexPathForItemAtPoint:p];
    if (indexPath == nil)
    {
        NSLog(@"couldn't find index path");            
    }
    else 
    {
        // get the cell at indexPath (the one you long pressed)
        UICollectionViewCell* cell =[self.coll_out cellForItemAtIndexPath:indexPath];
        // do stuff with the cell
    }
}

还尝试了委托方法:

- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
    NSMutableArray *item1=[arr_final objectAtIndex:indexPath.section];
    NSMutableArray *item2=[arr_final objectAtIndex:newIndexPath.section];
    NSLog(@"%@ %@",item1,item2);
    NSString *index = [item1 objectAtIndex:indexPath.item];
    [item1 removeObjectAtIndex:indexPath.item];
    [item2 insertObject:index atIndex:newIndexPath.item];
}

功能就像拖放一样。我见过的例子

请给我正确的方法和代码来刷到附近的单元格。 谢谢...

【问题讨论】:

    标签: ios objective-c drag-and-drop uiimageview uicollectionview


    【解决方案1】:

    实际上我一直在使用LXReorderableCollectionViewFlowLayout,它非常适合您,并且在他们的存储库中也有一个示例。起初我不建议您使用滑动手势,因为它与 UICollectionView 的内部手势处理高度冲突,但如果您确定需要它,您必须实现添加手势的委托方法并解决同时手势,因为它正在执行 LXReordableCollectionViewFlowLayout:

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
        if ([self.panGestureRecognizer isEqual:gestureRecognizer]) {
            return (self.selectedItemIndexPath != nil);
        }
        return YES;
    }
    
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
        if ([self.longPressGestureRecognizer isEqual:gestureRecognizer]) {
            return [self.panGestureRecognizer isEqual:otherGestureRecognizer];
        }
    
        if ([self.panGestureRecognizer isEqual:gestureRecognizer]) {
            return [self.longPressGestureRecognizer isEqual:otherGestureRecognizer];
        }
    
        return NO;
    }
    

    无论如何,我不建议您重新实现 LXReordableCollectionViewFlowLayout 中所做的事情,并将其用于您的需要。如果您使用 Storyboard,则需要将 UICollectionView 放入 UIViewController 并将默认 UICollectionViewFlowLayout 类更改为 LXReorderableCollectionViewFlowLayout 就像 此外,您的 UICollectionView 委托应符合下一个协议:LXReorderableCollectionViewDataSource(扩展 UICollectionViewDataSource)和 LXReorderableCollectionViewDelegateFlowLayout(扩展 UICollectionViewDelegateFlowLayout)允许您使用您的类。根据您的需要,只需提供下一个方法就足够了:

    - (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath {
        id from = [items objectAtIndex:fromIndexPath.item];
        id to = [items objectAtIndex:toIndexPath.item];
    
        [items replaceObjectAtIndex:fromIndexPath.item withObject:to];
        [items replaceObjectAtIndex:toIndexPath.item withObject:from];;
    }
    
    - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
    {
        return YES;
    }
    
    - (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath
    {
        return YES;
    }
    

    要获得您需要的行为,您必须进入 LXReorderableCollectionViewFlowLayout 类并更改 invalidateLayoutIfNecessary 方法,以便它执行另一种更新,而不是以前:

    - (void)invalidateLayoutIfNecessary {
        NSIndexPath *newIndexPath = [self.collectionView indexPathForItemAtPoint:self.currentView.center];
        NSIndexPath *previousIndexPath = self.selectedItemIndexPath;
    
        if ((newIndexPath == nil) || [newIndexPath isEqual:previousIndexPath]) {
            return;
        }
    
        if ([self.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:canMoveToIndexPath:)] &&
            ![self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath canMoveToIndexPath:newIndexPath]) {
            return;
        }
    
        self.selectedItemIndexPath = newIndexPath;
    
        if ([self.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:willMoveToIndexPath:)]) {
            [self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath willMoveToIndexPath:newIndexPath];
        }
    
        __weak typeof(self) weakSelf = self;
        [self.collectionView performBatchUpdates:^{
            __strong typeof(self) strongSelf = weakSelf;
            if (strongSelf) {
                // NOTE: cells swipe
                [strongSelf.collectionView moveItemAtIndexPath:previousIndexPath toIndexPath:newIndexPath];
                [strongSelf.collectionView moveItemAtIndexPath:newIndexPath toIndexPath:previousIndexPath];
    
                // NOTE: it was here previously
                // [strongSelf.collectionView deleteItemsAtIndexPaths:@[ previousIndexPath ]];
                // [strongSelf.collectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
            }
        } completion:^(BOOL finished) {
            __strong typeof(self) strongSelf = weakSelf;
            if ([strongSelf.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:didMoveToIndexPath:)]) {
                [strongSelf.dataSource collectionView:strongSelf.collectionView itemAtIndexPath:previousIndexPath didMoveToIndexPath:newIndexPath];
            }
        }];
    }
    

    它适用于靠近您初始项目的单元格,但是一旦您的卡移动,它可能会误导用户下一步将其移动到哪里,无论如何只需尝试一下,看看它是如何进行的。请记住,您可以通过 collectionView:itemAtIndexPath:canMoveToIndexPath: 方法控制项目的可用移动。

    希望对您有所帮助。

    【讨论】:

    • 它工作得很好......但问题是当我将一个项目移动到下排或上排时,整行的项目会向前或向后移动一步。我只想交换两个单元格的位置。
    • 我调整了一个答案,所以现在它应该可以正常工作了
    • 不..它仍然按照我在上面的评论中提到的那样做。:-(
    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多