scrollViewWillEndDragging: withVelocity: targetContentOffset: ne fonctionne pas sur les bords D'un UISCrollView

J'essaie d'implémenter une barre d'onglets personnalisée qui est défilante et a une pagination à chaque élément de la barre d'onglets. Pour cela, j'utilise le délégué scrollViewWillEndDragging: withVelocity: targetContentOffset: qui fonctionne parfaitement avec un problème.

La façon dont ma pagination fonctionne est, si le contentOffset est près du bon élément, le targetContentOffset change pour le décalage de cet élément. Même chose pour le côté gauche.

Le problème est, chaque fois que je suis à la moitié gauche du premier élément et la droite du dernier (la vue de défilement fonctionne horizontalement) il est censé aller à ContentOffset 0 et le décalage de contenu de l'élément le plus à droite (moins ceux à l'écran), mais ce n'est pas le cas.

J'ai vérifié avec le débogueur et le targetContentOffset- > x est en effet 0 (dans le premier cas-à gauche de l'élément le plus à gauche). Donc, le problème est que UIScrollView ne défile pas là. Je suis perdu.

Voici mon délégué implémenté:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                 withVelocity:(CGPoint)velocity
          targetContentOffset:(inout CGPoint *)targetContentOffset{
     NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
     targetContentOffset->x = index * self.tabWidth;
}

Voici le diagramme expliquant ce que je veux faire.

|-------|-------|-------|-------|-------|-------|-------|
|       |       |       |       |       |       |       |
|       |       |       |       |       |       |       |
|_______|_______|_______|_______|_______|_______|_______|

        |_______________________________________|
         where it is and i scroll it to the left

   <----|

   |_______________________________________|
              where it would stop

|_______________________________________|
        where i want it to stop
27
demandé sur dvieira 2012-06-04 15:23:35

5 réponses

C'est un problème connu, il semble. Après une enquête et de parler à d'autres personnes, il a été suggéré qu'il pourrait être un bug, qui s'est avéré être correct. Je l'ai signalé à Apple et a-t-il été marqué comme doublon mais est toujours ouvert. Juste répondre pour ceux d'entre vous avec le même problème. Je le contournerai comme le suggère Big Papoo, en utilisant un décalage proche de ce que je veux (0.1 semble le faire). De même pour l'extrémité droite.

14
répondu dvieira 2012-06-27 11:27:17

Problème corrigé sur iOS 6.0.

Maintenant, cela fonctionne comme il se doit.

9
répondu Rany A. Ishak 2012-10-10 13:08:19

J'ai essayé de définir le décalage final à quelque chose de légèrement inférieur à zéro ou à la taille du contenu comme suggéré par Big Papoo mais j'ai remarqué que cela supprime le rebond de défilement. Ma solution à cela était de vérifier le targetContentOffset d'origine pour voir s'il est égal à zéro ou le contentSize et le laisser si c'est:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {

    float expectedOffset = targetContentOffset->x;
    if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.

    float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.

    // Adjust the offset to make sure it works.
    if (targetOffset == 0) targetOffset = 1;
    else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;

    targetContentOffset->x = targetOffset;
}

Vous pouvez bien sûr utiliser scrollViewDidEndDecelerating: pour déplacer le scrollview de 1 point.

8
répondu Adam Swinden 2012-09-18 11:13:12

J'ai trouvé 2 comportements non documentés que vous pouvez étudier : - Mettre zéro comme le décalage final ne fonctionne pas, je suggère de mettre 1 ou quelque chose de plus grand que zéro (0.5 peut fonctionner, non testé) - Vous feriez mieux de vérifier le signe de vitesse et de calculer votre décalage final pour être sur le côté gauche ou droit du point actuel où l'utilisateur supprimé est le doigt. N'essayez pas de faire reculer le défilement de l'autre côté.

3
répondu Big Papoo 2012-06-26 23:37:20

Si vous utilisez une vue de table horizontale, alors dans votre scrollViewWillEndDragging: withVelocity: targetContentOffset: function, Vous pouvez appeler:

[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];

J'ai trouvé que cela fonctionnait beaucoup mieux que d'essayer de manipuler targetContentOffset->y dans une vue de table horizontale.

0
répondu Mr. T 2012-08-09 00:36:47