67 votes

UIScrollView fonctionne comme prévu, mais scrollRectToVisible : ne fait rien.

J'ai utilisé UIScrollView avant, et je l'utilise maintenant, et je n'ai jamais eu de problème. Je l'ajoute maintenant à une ancienne application et, bien qu'il fonctionne comme prévu (je peux regarder le contenu, le faire défiler avec mon doigt, toutes les limites et les tailles sont bien configurées de sorte qu'il n'y a pas d'espace vide dans le contenu, etc. scrollToRectVisible pour fonctionner. J'ai même simplifié l'appel pour qu'il se déplace simplement à la position 0,0 :

 [scrollView scrollRectToVisible:CGRectMake(0, 0, 10, 10) animated:YES];

ou le déplacer à 0,200 :

 [scrollView scrollRectToVisible:CGRectMake(0, 200, 10, 10) animated:YES];

J'ai même créé une application rapide pour tester cela et je peux obtenir scrollRectToVisible pour y fonctionner comme je l'espère. Mais dans mon ancienne application, je n'arrive pas à lui faire faire quoi que ce soit.

Je peux faire défiler le scrollView avec setContentOffset: mais ce n'est pas ce que je veux.

Cette scrollView et son contenu sont définis dans la nib par IB et utilisés avec une IBOutlet. Le seul code que j'utilise dans mon application pour gérer le scrollView est le suivant

 [scrollView setContentSize:CGSizeMake(scrollView.contentSize.width, imageView.frame.size.height)];

(Je ne suis intéressé que par le défilement vertical, pas horizontal).

Quelqu'un a-t-il rencontré un tel problème ?

J'ai comparé les attributs de scrollView dans les deux applications et ils sont identiques.

ADDENDUM :

Mon cadre scrollViews est : 0.000000 0.000000 480.000000 179.000000

Mon scrollViews contentSize est : 0.000000 324.000000

Il agit toujours comme si le rectangle vers lequel je veux défiler était déjà visible et qu'aucun défilement n'était nécessaire. Je ne suis pas sûr que ce soit ce qui se passe. C'est tout simplement la chose la plus étrange. Cela semble si facile à résoudre...

ADDENDUM #2 :

C'est comme ça que je me débrouille sans scrollRectToVisible :

CGPoint point = myRect.origin;
if (![clefScrollView pointInside:point withEvent:nil]) {
    point.x = 0;
    if (point.y > clefScrollView.contentSize.height - clefScrollView.bounds.size.height)
        point.y = clefScrollView.contentSize.height - clefScrollView.bounds.size.height;
    [clefScrollView setContentOffset:point animated: YES];
}

Tout le reste de ce scrollView fonctionne comme prévu, mais scrollRectToVisible . POURQUOI ? !? Des suppositions sauvages ?

118voto

mahboudz Points 23653

Plus d'un mois plus tard, j'ai enfin trouvé la solution. Bien que l'alternative ci-dessus ait bien fonctionné, cela m'a dérangé et je devais enfin trouver une solution. Il s'avère que c'était une erreur stupide.

Voici l'ancien code dans mon viewDidLoad, où je configure le scrollView :

[clefScrollView setContentSize:CGSizeMake(clefScrollView.contentSize.width, clefView.frame.size.height)];

La valeur de la hauteur ou de la largeur d'un scrollView ne peut pas être 0 ! Je pense que cela m'a échappé parce que je supposais que les tailles des ScrollViews commençaient avec une taille valide, et j'ai manqué le fait qu'une dimension était nulle !

Ça marche :

[clefScrollView setContentSize:CGSizeMake(clefView.frame.size.width, clefView.frame.size.height)];

J'espère que cela aidera quelqu'un d'autre. J'ai certainement passé beaucoup trop de temps à essayer de déboguer ça.

0 votes

Bon travail de détective, mahboudz. pour info, je soupçonne que le problème n'est pas précisément que le ScrollView ne peut pas avoir une dimension de taille zéro, mais plutôt qu'il doit être suffisamment grand pour contenir le rectangle demandé ! merci, Orion

0 votes

Merci ! Je me suis fait piquer par ça aussi (je réglais la hauteur mais pas la largeur).

3 votes

Ce n'est PAS tout à fait correct - voir la réponse d'Orion ci-dessous (j'avais une largeur/hauteur non nulle, ce n'est pas '0' qui cause le problème...).

51voto

Jonathan Sterling Points 11628

Ouais, je n'ai pas eu de succès avec scrollRectToVisible:animated: mais setContentOffset:animated: ça marche toujours pour moi. Par curiosité, pourquoi ne voulez-vous pas utiliser setContentOffset:animated: ? Cela semble être la bonne solution.

7 votes

Malheureusement, setContentOffset fera défiler jusqu'au point, qu'il soit déjà visible ou non. Je pourrais faire le travail supplémentaire de déterminer si le point est visible ou non, cependant, je suis toujours curieux de savoir pourquoi scrollRectToVisible ne fonctionne pas, alors que je le vois fonctionner dans mon propre échantillon et d'autres échantillons sur le net. Je dois faire quelque chose de mal, mais avec seulement trois ou quatre lignes de code pour le scrollView, je ne vois pas quoi !

5voto

Michael Colon Points 31

Vous pouvez vérifier que l'élément de la scrollView delaysContentTouches a pour valeur NO .

Si vous appelez la méthode scrollRectToVisible ou setContentOffset à partir d'une touche dans une sous-vue de votre scrollView, alors votre scrollView pourrait retarder les touches.

Assurez-vous donc de définir les éléments suivants dans votre scrollView.

scrollView.delaysContentTouches = NO;

Vous serez très probablement en mesure de déplacer le scrollView avec et sans l'animation définie sur YES.

1voto

Rugoso Points 1

Je l'avais comme ça et ça n'a pas marché.

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width, someKnownValue);

Je changeais juste la hauteur de la contentSize Je ne pensais pas que cela me poserait un problème, mais c'est le cas...

j'ai dû le changer en ceci

scrollView.contentSize = CGSizeMake(someOtherKnownValue, someKnownValue);

il s'avère que scrollView.contentSize.width n'est pas nécessairement défini comme une valeur valide dès le départ, il vaut mieux lui donner une valeur spécifique.

0voto

aimacworx Points 364

La solution proposée ci-dessus peut encore donner lieu à une erreur si vous n'avez pas défini le cadre pour le "clefScrollView".

Si vous utilisez la solution ci-dessus et que vous rencontrez toujours le même problème, assurez-vous que vous avez initialisé votre cadre scollView (dans ce cas clefScrollView) avant de définir la vue de contenu.

    clefScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320,450)];

    [clefScrollView setContentSize:CGSizeMake(clefView.frame.size.width, clefView.frame.size.height)];

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X