2010-03-02 6 views
3

Configuration: J'ai un UITableView, chaque UITableViewCell a un UIScrollView. Ce que j'essaie de faire est d'obtenir tous les UIScrollViews pour faire défiler ensemble, de sorte que lorsque vous faites défiler l'un d'eux tous les UIScrollViews semblent faire défiler simultanément.Comment faire défiler un ensemble de UIScrollViews ensemble?

Ce que j'ai fait est sous-classe UITableView de sorte qu'il a un tableau de tous les UIScrollViews dans ses cellules de tableau. J'ai ensuite transmis TouchesBegan, TouchesMoved, TouchesCancelled et TouchesEnded du UITableView à tous les UIScrollViews dans la matrice.

Cela ne semble pas fonctionner. Les UIScrollViews ne défilent pas! La seule façon que j'ai réussi à faire fonctionner ceci est d'appeler la méthode setContentOffset: sur les scrollviews. Cependant, ceci est une très mauvaise solution, car il ne vous donne pas les caractéristiques de balayage et de décélération du UIScrollView.

Des idées sur pourquoi mes méthodes touch ne parviennent pas à la UIScrollViews? Ou une meilleure façon de mettre en œuvre cela?

Répondre

2

J'ai fait quelque chose de "similaire" où j'avais 4 scrollViews incasés dans une vue parente. J'ai placé un scrollView à l'intérieur d'un UIView, cet UIView a été passé un délégué de son parentView, qui était la vue qui a gardé la trace de tous les scrollViews. L'UIView contenant un scrollVIew implémenté le UIScrollViewDelegate et cette méthode;

- (void)scrollViewDidScroll:(UIScrollView *) theScrollView { 

    [self.delegate scrolling:[self.scrollView contentOffSet]]; 

} 

Maintenant, la vue parent ai fait sur tous les scrollViews:

- (void) scrolling:(CGFloat) offset { 

    for(UIScrollView *s in self) { 
     [s setContentOffset:offset animated:YES]; 
    } 
} 

Il est bien sûr un peu de pression sur la CPU, mais le défilement plusieurs vues sera que en aucun cas:/

Espérons que c'était quelque chose dans le sens de ce dont vous aviez besoin, et que cela avait du sens.

Ajouté:

Je m'a pris 8 chemins différents et beaucoup de chaos de masse avant que je fait le travail. J'ai laissé tomber l'approche touchedBegan tôt, il n'y a tout simplement aucun moyen d'écrire quelque chose qui se rapproche de l'application de balayage, de flick et de scroll des pommes.

Je ne sais pas si la tableview et scrollview vont «voler» les événements tactiles des autres, mais comme je peux le lire dans votre description, vous avez fait fonctionner cette partie.

Une idée de suivi pour faciliter l'utilisation du processeur. ajoutez chaque scrollview à une cellule, définissez sa balise = 14, maintenant lorsque le défilement demande uniquement toutes les cellules visibles, demandez viewWithTag = 14, définissez contentOffset sur ceci. Enregistrez le contenu globalement de manière à pouvoir l'affecter aux cellules défilées sur l'écran au cellForRowAtIndexPath.

Définissez donc offSet sur une propriété globale. Dans cellForRowAtIndexPath recherchez l'affichage avec tag = 14, définissez son décalage. De cette façon, vous n'avez même pas besoin d'une référence au scrollViews seul le délégué.

+0

solution intéressante ah. Je vais essayer cette fois que je rentre à la maison. Je n'ai pas pensé à utiliser setContentOffset basé sur scrollViewDidScroll, je l'ai fait en fonction des touches. Comme vous pouvez l'imaginer, les réglages sont animés: OUI pour chaque touche provoquant un chaos massif. –

+0

Ricki, d'excellentes suggestions, allez l'essayer ce soir. Merci!! –

+0

J'ai fait presque exactement cette solution avant et cela fonctionne très bien. le seul changement est que je l'ai fait animé: NON. le 'scrollViewDidScroll:' va être appelé extrêmement souvent pendant le défilement, de sorte que le reste apparaîtra animé de toute façon sans le définir explicitement. Cela permettra d'économiser du temps CPU pour la même expérience pour l'utilisateur. –

6

Ok, ça marche. Merci pour les conseils Ricki!

2 choses à ajouter à la solution de Ricki, si vous voulez éviter une boucle infinie, vous devez vérifier si les propriétés de suivi ou de glissement du scrollView sont définies.Cela assurera que seul le ScrollView qui est réellement déplacé appelle le délégué.

- (void)scrollViewDidScroll:(UIScrollView *) theScrollView { 
     if (theScrollView.dragging || theScrollView.tracking) 
       [self.delegate scrolling:[theScrollView contentOffSet]]; 
} 

En outre, dans la méthode de défilement du délégué, je me mis à animé NON, c'est débarrassé du délai entre le premier coup et les autres scrollviews obtenir mis à jour.

+0

Vous êtes les bienvenus, génial que vous avez travaillé les kinks si vite :) Mon premier défi était un peu différent du vôtre mais agréable d'entendre que la solution était applicable dans d'autres conceptions aussi bien. – RickiG

+0

Wow! travaillé comme un charme. – Jirune

0

Si vous avez de tailles différentes UIScrollViews et que vous utilisez la pagination, cela fonctionne très bien:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView { 
    #pragma unused(_scrollView) 
    categoryPageControlIsChangingPage = NO; 
    for (UIImageView *iv in [categoryScrollView subviews]) { 
     iv.alpha = (iv.tag != categoryPageControl.currentPage+1)?0.5f:1.0f; 
     ILogPlus(@"%i %i", iv.tag, categoryPageControl.currentPage+1); 
    } 
    [self scrolling:_scrollView]; 
} 

- (void)scrolling:(UIScrollView *)sv { 
    CGFloat offsetX = sv.contentOffset.x; 
    CGFloat ratio = offsetX/sv.contentSize.width; 

    if ([sv isEqual:categoryScrollView]) { 
     [categoryScrollViewLarge setContentOffset:CGPointMake(ratio*categoryScrollViewLarge.contentSize.width, 0) animated:YES]; 
    }else { 
     [categoryScrollView setContentOffset:CGPointMake(ratio*categoryScrollView.contentSize.width, 0) animated:YES]; 
    } 
} 
Questions connexes