0

UICollectionViewいくつかのアイテムをロックしながら、セルを並べ替えています。ロックされていないアイテムを並べ替えると、ロックされているアイテムも並べ替えられます。どうすれば配列をシャッフルできますか? または、要素のレイアウト属性を変更する必要がありますか?

- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath {


    PlayingCard *playingCard = [self.deck objectAtIndex:fromIndexPath.item];

    [self.deck removeObjectAtIndex:fromIndexPath.item];

    [self.deck insertObject:playingCard atIndex: toIndexPath.item];


    [collectionView performBatchUpdates:^{
        NSIndexPath *deletedItemIndexPath = [NSIndexPath indexPathForRow:fromIndexPath.row inSection:fromIndexPath.section];
        NSIndexPath *insertedItemIndexPath = [NSIndexPath indexPathForRow:newToIndexPath.row inSection:toIndexPath.section];

        [collectionView deleteItemsAtIndexPaths:@[ deletedItemIndexPath ]];
        [collectionView insertItemsAtIndexPaths:@[ insertedItemIndexPath ]];
    } completion:^(BOOL finished) {

    }];

}

- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath {
    PlayingCard *playingCard = [self.deck objectAtIndex:indexPath.item];
    return !playingCard.isLocked;
}

- (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath {
    return ([self collectionView:collectionView canMoveItemAtIndexPath:fromIndexPath] &&
                    [self collectionView:collectionView canMoveItemAtIndexPath:toIndexPath]);
}

- (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];
    }


}

- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)gestureRecognizer {
    switch(gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan: {
            NSIndexPath *currentIndexPath = [self.collectionView indexPathForItemAtPoint:[gestureRecognizer locationInView:self.collectionView]];

            if ([self.dataSource respondsToSelector:@selector(collectionView:canMoveItemAtIndexPath:)] &&
               ![self.dataSource collectionView:self.collectionView canMoveItemAtIndexPath:currentIndexPath]) {
                return;
            }

            self.selectedItemIndexPath = currentIndexPath;

            if ([self.delegate respondsToSelector:@selector(collectionView:layout:willBeginDraggingItemAtIndexPath:)]) {
                [self.delegate collectionView:self.collectionView layout:self willBeginDraggingItemAtIndexPath:self.selectedItemIndexPath];
            }

            UICollectionViewCell *collectionViewCell = [self.collectionView cellForItemAtIndexPath:self.selectedItemIndexPath];

            self.currentView = [[UIView alloc] initWithFrame:collectionViewCell.frame];

            collectionViewCell.highlighted = YES;
            UIImageView *highlightedImageView = [[UIImageView alloc] initWithImage:[collectionViewCell LX_rasterizedImage]];
            highlightedImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            highlightedImageView.alpha = 1.0f;

            collectionViewCell.highlighted = NO;
            UIImageView *imageView = [[UIImageView alloc] initWithImage:[collectionViewCell LX_rasterizedImage]];
            imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            imageView.alpha = 0.0f;

            [self.currentView addSubview:imageView];
            [self.currentView addSubview:highlightedImageView];
            [self.collectionView addSubview:self.currentView];

            self.currentViewCenter = self.currentView.center;

            __weak typeof(self) weakSelf = self;
            [UIView
             animateWithDuration:0.3
             delay:0.0
             options:UIViewAnimationOptionBeginFromCurrentState
             animations:^{
                 __strong typeof(self) strongSelf = weakSelf;
                 if (strongSelf) {
                     strongSelf.currentView.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
                     highlightedImageView.alpha = 0.0f;
                     imageView.alpha = 1.0f;
                 }
             }
             completion:^(BOOL finished) {
                 __strong typeof(self) strongSelf = weakSelf;
                 if (strongSelf) {
                     [highlightedImageView removeFromSuperview];

                     if ([strongSelf.delegate respondsToSelector:@selector(collectionView:layout:didBeginDraggingItemAtIndexPath:)]) {
                         [strongSelf.delegate collectionView:strongSelf.collectionView layout:strongSelf didBeginDraggingItemAtIndexPath:strongSelf.selectedItemIndexPath];
                     }
                 }
             }];

            [self invalidateLayout];
        } break;
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateEnded: {
            NSIndexPath *currentIndexPath = self.selectedItemIndexPath;

            if (currentIndexPath) {
                if ([self.delegate respondsToSelector:@selector(collectionView:layout:willEndDraggingItemAtIndexPath:)]) {
                    [self.delegate collectionView:self.collectionView layout:self willEndDraggingItemAtIndexPath:currentIndexPath];
                }

                self.selectedItemIndexPath = nil;
                self.currentViewCenter = CGPointZero;

                UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForItemAtIndexPath:currentIndexPath];

                __weak typeof(self) weakSelf = self;
                [UIView
                 animateWithDuration:0.3
                 delay:0.0
                 options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                     __strong typeof(self) strongSelf = weakSelf;
                     if (strongSelf) {
                         strongSelf.currentView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
                         strongSelf.currentView.center = layoutAttributes.center;
                     }
                 }
                 completion:^(BOOL finished) {
                     __strong typeof(self) strongSelf = weakSelf;
                     if (strongSelf) {
                         [strongSelf.currentView removeFromSuperview];
                         strongSelf.currentView = nil;
                         [strongSelf invalidateLayout];

                         if ([strongSelf.delegate respondsToSelector:@selector(collectionView:layout:didEndDraggingItemAtIndexPath:)]) {
                             [strongSelf.delegate collectionView:strongSelf.collectionView layout:strongSelf didEndDraggingItemAtIndexPath:currentIndexPath];
                         }
                     }
                 }];
            }
        } break;

        default: break;
    }
}
4

1 に答える 1

1

あなたがする必要があるのはこれです:

ユーザーがセルを移動すると、そのセルが新しいインデックス パスに配置されます (置き換えられるセルがロックされていない場合)。

次に、置き換えられたもので、そのインデックス行を +1 移動する必要があります。これはおそらくループで実行する必要があり、次のセルがロックされていないことを確認する必要があります。ロックされている場合は、行をさらに 1 増やします。次に例を示します。

CELL 1

CELL 2 - locked

CELL 3

に移動CELL 3CELL 1ます。CELL 2次に、がロックされているかどうかを確認する必要があります。そうである場合 (この例のように)、代わりに移動CELL 1CELL 3ます。

//This is the card that is moving
PlayingCard *cardToMove = [self.deck objectAtIndex:fromIndexPath.row];

//This is the card that is being replaced and also needs to move.
PlayingCard *cardToReplace = [self.deck objectAtIndex:toIndexPath.row];


//We need to check if the next cell is a position which we can occupy with the cardToMove. This is where the loop will go. 
NSInteger increment = 1;

PlayingCard *cardNextToReplaced = [self.deck objectAtIndex:toIndexPath.row + increment];

while (cardNextToReplaced.isLocked) {

    increment ++;
    cardNextToReplaced == [self.deck objectAtIndex:toIndexPath.row + increment];

}

//This should now be a 'free space'
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:toIndexPath.row + increment inSection:toIndexPath.section];


//So now you just move the cardToMove to it's new index path. The cardToReplace should be moved the newly created `indexPath` above this. That should be a 'free space'.
于 2014-04-28T10:47:33.630 に答える