Résumé exécutif: strong>
Durée les détails: strong>
J'ai des problèmes lors du zoomez avec Pour illustrer le problème, j'ai modifié l'exemple d'exemple d'Apple, ZoomingPDFViewer. Le code est sur GitHub: https://github.com/dirkmaas/zoomingpdfviewer-bug p>
Un robinet causera Par exemple, dites le Mais si le une note sur l'interface utilisateur: p>
J'ai remarqué que si Voici un résumé de ce que j'ai fait (le code dans GitHub inclut ces changements): P>
Merci beaucoup pour avoir porté avec moi, et n'importe quelle aide! P> UISCrollView CODE> fait une modification non désirée à la valeur de
contentoffset CODE>, entraînant ainsi l'application pour afficher le mauvais emplacement dans le document vu. Le changement indésirable se produit conjointement à une modification animée de la vue
Zoomscale Code>. P>
catiledlayer code> dans un
uiscrollview code>. Le
catiledlayer code> contient un PDF et lorsque
contentoffset code> est dans une certaine plage, lorsque je zoomer, le
contentoffset code> est modifié (c'est le bogue) avant que le zoom se produise. Le
contentoffset code> semble être modifié dans le code d'Apple. P>
zoomscale code> pour être modifié à 0,5, en utilisant
animatewithduration code>, zoomez donc. Si le
UiscrollView code> 'S
contentoffset.y code> est inférieur à environ 2700 ou supérieur à 5900, le
ZoomScale code> L'animation fonctionne bien. Si le robinet se produit lorsque
contentoffset.y code> est entre ces deux valeurs, le
contentoffset.y code> sautera (non animé) à environ 2700, puis le
zoomscale < / Code> L'animation se produira, mais le défilement se produira en même temps, de sorte que lorsque l'animation est terminée, le
contentoffset.y code> est l'endroit où il devrait être. Mais d'où vient le saut? P>
contentoffset.y code> est 2000 lorsque l'écran est taraudé: le
zoomscale code> L'animation fonctionne tout à fait;
contentoffset.y code> n'est pas modifié. p>
contentoffset.y code> est 4000 lorsque l'écran est taraudé: le
contentoffset.y code> sautera, sans animation, à environ 2700, puis zoomer et faire défiler va commencer à partir de ce point et se produire en même temps. Lorsque l'animation est terminée, il semble que nous ayons zoomé directement à partir de 4000, nous nous retrouvons donc au bon endroit, mais le comportement est faux. P>
zoomscale code> à 0,5; Le changement est animé li>
ul>
zoomscale code> est supérieur à 0,5, le saut n'est pas si gros. Également, si j'utilise
setzoomscale: animé: code> au lieu de
animatewithduration code>, le bogue disparaît, mais je ne peux pas l'utiliser parce que j'ai besoin de chaîner des animations. P>
pdfscrollview * ScrollView; code> à
zoomingpdfviewervieflontroller code> Classe Li>
loadview code> in
zoomingpdfvievieviewcontroller code> Pour initialiser
ScrollView code> au lieu de
SV code> li>
ViewDiDload code>,
HandletApfrom: reconnaître code> et
zoomout code> à
zoomingpdfviewerviewontroller code> dans pdfscrollview.m li>
ScrollViefDidDendZooming: Avec vue: ATSCALE CODE> et
ScrollviewWillBeGinzoom: CODE> Parce qu'ils font des trucs dans l'arrière-plan d'image qui distrait du problème de la question li>
ul>
5 Réponses :
Une des choses les plus difficiles à comprendre sur le zoom est qu'il arrive toujours autour d'un point appelé point d'ancrage. Je pense que la meilleure façon de comprendre est d'imaginer un système de coordonnées superposé sur un autre. Say A est votre système de coordonnées externe, B est l'intérieur (B sera le ScrollView). Lorsque le décalage de B est (0,0) et la balance est de 1,0, le point B (0,0) correspond à un (0,0) et dans le général B (x, y) = A (x, y) = ).
En outre, si le décalage de B est (XOFF, YOFF) puis B (x, y) = A (x - xoff, y-yoff). Encore une fois, cela suppose toujours que l'échelle de zoom est de 1,0. P>
Maintenant, laissez le décalage être à nouveau (0,0) à nouveau et imaginez ce qui se passe lorsque vous essayez de zoomer. Il doit y avoir un point sur l'écran qui ne bouge pas lorsque vous zoomez et que tout autre point se déplace vers l'extérieur de ce point. C'est ce que définit le point d'ancrage. Si votre ancre est (0,0), le point de gauche reste fixé lorsque tous les autres points progressent et à droite. Dans ce cas, le décalage reste le même. P>
si votre point d'ancrage est (0,5, 0,5) (le point d'ancrage est normalisé, c'est-à-dire 0 à 1, de sorte que 0,5 est à mi-parcours), alors le point central reste corrigé pendant que tous les autres points se déplacent vers l'extérieur. Cela signifie que le décalage doit changer pour refléter cela. Si c'est sur un iPhone en mode portrait et que vous zoomez à l'échelle 2.0, la valeur de point d'ancrage X déplacera la moitié de la largeur de l'écran, 320/2 = 160. p>
La position réelle du contenu Vues de défilement L'écran est défini à la fois par le décalage et le point d'ancrage. Donc, si vous modifiez simplement le point d'ancrage de calques en dessous sans effectuer une modification correspondante au décalage, vous verrez que la vue apparaît pour passer à un emplacement différent, même si le décalage est identique. P>
Je suis Devinez que c'est le problème sous-jacent ici. Lorsque vous animez le zoom, l'animation de base doit choisir un nouveau point d'ancrage afin que le zoom "semble" correct. Cela modifiera également le décalage afin que la région visible vise la région visible à l'écran ne saute pas. Essayez de vous connecter à l'emplacement du point d'ancrage à différents moments tout au long de ce processus (il est défini sur la calayeuse sous-jacente de n'importe quelle vue que vous accédez à une propriété Vues "Couche"). P>
aussi, veuillez consulter la documentation ici pour de jolies images et probablement Une meilleure meilleure description de la situation que celle que j'ai donnée ici :) p>
Enfin, voici un extrait de code que j'ai utilisé dans une application pour modifier le point d'ancrage d'une couche sans passer à l'écran. < / p>
Merci, mais je ne pense pas que c'était ça. Le code n'essaie pas de changer la valeur code> anchorpoint code> directement ou indirectement, et je l'ai enregistré avant et après le zoom, et les deux fois, il s'agissait de la valeur par défaut (0,5, 0.5). De plus, par sa nature, anchorpoint code> est toujours à l'écran, visible, ce qui signifie que tout saut serait inférieur à 1 écran de l'écran, mais le saut que je vois des causes
contentoffset.y < / Code> Pour changer de milliers - plusieurs écrans loin. Pour moi, cela prouve que AnchorPoint n'est pas le problème, à moins que je sois mal compris quelque chose.
Vous devez utiliser ScrollViewDidLendZoom Sinon, je pense que vous devrez supprimer l'utilisation de la propriété ZoomScale de l'UISCrollView et implémentera plutôt du zoomer complètement manuellement, par ex. http://jonathanwatmough.com/ 2008/12 / Mise en œuvre-Tap-To-Zoom-in-Uiscrollview-On-an-iPhone / . P>
J'avais de nombreux bugs avec zoomer lorsque ma fonction de visualisationForzoomingScrollViewsCrollview retourne directement à ScrollView.
Beaucoup de ces comportements étranges ont disparu après avoir défini une vue à l'intérieur de la vue ScrollView qui contenant tout et le renvoie dans le point de vue de la vueForzoomingScrollView. Peut-être que cela devrait résoudre votre problème aussi: P>
-(void) someIntializationFunction { [myScrollView addSubView:self.globalContainer]; // Now had everything in the container and not in the scrollView directly .... } - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; { return self.globalContainer; }
Je joue avec le code que vous avez posté et je pense avoir trouvé ce qui se passe. Lorsque vous faites une animation de bloc comme dans votre code:
[UIView animateWithDuration:4.0 animations:^ { self.scrollView.zoomScale = 0.5; } completion:nil];
Je pense que vous devez manipuler le contentInset et / ou le contentoffset vous-même, sur chaque événement de défilement. Manipuler les points d'ancrage ne vous aideront pas. Regarde Cette question et ma réponse. P>
Qu'entendez-vous en ayant besoin de chaîner des animations? Pourquoi ne pouvez-vous pas utiliser
ScrollViefDidIdendZoom
@Michael Frederick - Bon point. C'est un travail autour, mais j'aime utiliser
animatewithduration: code> au lieu de
setzoomscale: animé: code> car, sauf si je manque quelque chose, ce dernier ne permet pas de contrôler la durée de la durée , et parce que les animations de bloc font un meilleur travail, à mon avis, de garder le code associé ensemble. Plus Apple semble nous encourager à utiliser des animations de blocs. Donc, peut-être que j'aurais dû dire "Je ne veux pas utiliser
setzoomscale: animé: code>." Merci pour le commentaire!