UICollectionView efficace glisser-déposer

Je suis en train d'essayer de mettre en œuvre la UITableView réorganisation de comportement à l'aide de UICollectionView.

Appelons un UItableView TV et un UICollectionView CV (pour clarifier l'explication suivante)

Je suis en fait, d'essayer de reproduire le drag&drop de la TV, mais je ne suis pas en utilisant le mode d'édition, la cellule est prête à être déplacée dès que la presse à long geste est déclenchée. Il fonctionne parfaitement, je suis en utilisant la méthode de déplacement de la CV, tout va bien.

- Je mettre à jour le contentOffset propriété de la CV pour gérer le défilement lorsque l'utilisateur fait glisser une cellule. Lorsqu'un utilisateur accède à un particulier rect en haut et en bas, je l'ai mise à jour de la contentOffset et le CV de défilement. Le problème, c'est lorsque l'utilisateur arrêter le déplacement du doigt, le geste ne pas envoyer de mise à jour qui rend le défilement s'arrêter et recommencer dès que l'utilisateur déplace son doigt.

Ce comportement est certainement pas naturel, je préfère continuer à faire défiler jusqu'à l'utilisateur de libérer le CV comme c'est le cas à la TÉLÉVISION. La TÉLÉVISION drag&drop expérience est géniale et j'ai vraiment envie de reproduire le même sentiment. Personne ne sait comment ils gèrent les faire défiler à la TÉLÉVISION lors de la réorganisation ?

  • J'ai essayé d'utiliser une minuterie pour déclencher le défilement de l'action à plusieurs reprises, tant que le geste, il est placé au bon endroit, le défilement a été terrible et pas très productif (très lente et irrégulière).
  • J'ai aussi essayé d'utiliser le PGCD pour écouter la geste de la poste dans un autre fil, mais le résultat est encore pire.

J'ai manqué de l'idée à ce sujet, donc si quelqu'un a la réponse je l'épouser!

Ici est la mise en œuvre de la appuyez de manière prolongée sur la méthode:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
    ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
    CGPoint gesturePosition = [sender locationInView:self.collectionView];
    NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:gesturePosition];

    if (sender.state == UIGestureRecognizerStateBegan)
    {
        layout.selectedItem = selectedIndexPath;
        layout.gesturePoint = gesturePosition; //Setting gesturePoint invalidate layout
    }
    else if (sender.state == UIGestureRecognizerStateChanged)
    {
        layout.gesturePoint = gesturePosition; //Setting gesturePoint invalidate layout
        [self swapCellAtPoint:gesturePosition];
        [self manageScrollWithReferencePoint:gesturePosition];
    }
    else
    {
        [self.collectionView performBatchUpdates:^
        {
            layout.selectedItem = nil;
            layout.gesturePoint = CGPointZero; //Setting gesturePoint invalidate layout
        } completion:^(BOOL completion){[self.collectionView reloadData];}];
    }
}

De rendre le CV de défilement, je suis en utilisant cette méthode:

- (void)manageScrollWithReferencePoint:(CGPoint)gesturePoint
{
    ReorganizableCVCLayout *layout = (ReorganizableCVCLayout *)self.collectionView.collectionViewLayout;
    CGFloat topScrollLimit = self.collectionView.contentOffset.y+layout.itemSize.height/2+SCROLL_BORDER;
    CGFloat bottomScrollLimit = self.collectionView.contentOffset.y+self.collectionView.frame.size.height-layout.itemSize.height/2-SCROLL_BORDER;
    CGPoint contentOffset = self.collectionView.contentOffset;

    if (gesturePoint.y < topScrollLimit && gesturePoint.y - layout.itemSize.height/2 - SCROLL_BORDER > 0)
        contentOffset.y -= SCROLL_STEP;
    else if (gesturePoint.y > bottomScrollLimit &&
             gesturePoint.y + layout.itemSize.height/2 + SCROLL_BORDER < self.collectionView.contentSize.height)
        contentOffset.y += SCROLL_STEP;

    [self.collectionView setContentOffset:contentOffset];
}
InformationsquelleAutor foOg | 2012-10-03