74 votes

Obtenir le visible rect d'un UIScrollView du contenu

Comment puis-je trouver les rect (CGRect) le contenu d'une affiche vue qui est visible sur l'écran.

myScrollView.bounds

Le code ci-dessus fonctionne quand il n'y a pas de zoom, mais dès que vous vous permettent de zoomer, elle tombe à un niveau de zoom autre que 1.

Pour clarifier, je veux un CGRect qui contient la zone visible de la faire défiler la vue du contenu, par rapport au contenu. (ie. si c'est un zoom à l'échelle 2, le rectangle de la taille de la moitié du défilement de la vue de la taille, si c'est à l'échelle de zoom de 0,5, ce sera le double.)

113voto

Trenskow Points 1748

Ou vous pouvez simplement les faire

CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:zoomedSubview];

84voto

Kenneth Ballenegger Points 1866

Pour répondre à ma propre question, surtout grâce à Jim Dovey de la réponse, qui n'a pas tout à fait faire l'affaire, mais m'a donné la base de ma réponse:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.bounds.size;

float theScale = 1.0 / scale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;

La principale différence est que la taille de la visibleRect devrait être scrollView.bounds.size, plutôt que d' scrollView.contentSize qui est de la taille de l'affichage du contenu. Également simplifié les maths un peu, et n'arrive pas à voir l'utilisation de la isless() qui enfreignent le code chaque fois qu'il est plus grand.

29voto

Jim Dovey Points 8384

Vous avez de la calculer à l'aide de UIScrollView de contentOffset et contentSize propriétés, comme suit:

CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.contentSize;

Vous pouvez ensuite vous connecter pour la santé mentale-test:

NSLog( @"Visible rect: %@", NSStringFromCGRect(visibleRect) );

Pour tenir compte de zoom (si ce n'est pas déjà fait par le contentSize de la propriété), vous devrez diviser chaque coordonnée par le zoomScale, ou pour de meilleures performances, vous devez multiplier par 1.0 / zoomScale:

CGFloat scale = (CGFloat) 1.0 / scrollView.zoomScale;
if ( isless(scale, 1.0) )      // you need to #include <math.h> for isless()
{
    visibleRect.origin.x *= scale;
    visibleRect.origin.y *= scale;
    visibleRect.size.width *= scale;
    visibleRect.size.height *= scale;
}

Aparté: j'utilise est(), isgreater(), isequal (), etc. à partir de mathématiques.h parce que ces va (sans doute) de faire la bonne chose au sujet de la "non-ordonnée" floating-point de la comparaison des résultats et d'autres étranges et merveilleux de l'architecture spécifique de la FP cas.

10voto

Frank Schmitt Points 7914

Version courte:

CGRect visibleRect = CGRectApplyAffineTransform(scrollView.bounds, CGAffineTransformMakeScale(1.0 / scrollView.zoomScale, 1.0 / scrollView.zoomScale));

Je ne suis pas sûr si cela est défini comportement, mais presque tous les UIView sous-classes ont l'origine de leur bounds (0,0). UIScrollViews, cependant, ont l'origine contentOffset.

6voto

Nikolay Shubenkov Points 287

un peu plus général:

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];

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