Question

Comment puis-je faire pour trouver le rect (CGRect) du contenu d'une vue affichée qui est réellement visible à l'écran.

myScrollView.bounds

Le code ci-dessus fonctionne quand il n'y a pas de zoom, mais dès que vous permettre de zoomer, il se casse à l'échelle de zoom autres que 1.

Pour clarifier, je veux un CGRect qui contient la zone visible du contenu de la vue de défilement, par rapport au contenu. (Ie. Si elle est une échelle de zoom 2, la taille du rect sera la moitié de la taille de la vue de défilement, si elle est à l'échelle de zoom 0.5, il sera double.)

Était-ce utile?

La solution 2

Répondre à ma propre question, en grande partie grâce à la réponse de Jim Dovey, qui n'a pas tout à fait faire l'affaire, mais m'a donné la base pour 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 doit être scrollView.bounds.size, plutôt que scrollView.contentSize qui est la taille de l'affichage du contenu. En outre simplifié les mathématiques un peu, et ne pas tout à fait voir l'utilisation du qui briserait isless() le code à chaque fois qu'il est plus.

Autres conseils

Ou vous pouvez simplement faire

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

Swift

let visibleRect = scrollView.convert(scrollView.bounds, to: zoomedSubview)

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

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

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

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

Pour tenir compte de zoom du zoomScale, ou pour une meilleure performance que vous multipliez par 1.0 / zoomScale (si cela est déjà fait par la propriété contentSize) vous devez diviser chaque coordonnez:

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;
}

En plus: J'utilise isless (), isgreater (), IsEqual (), etc. de math.h parce que ceux-ci (probablement) faire la bonne chose au sujet de « » désordonnées résultats de la comparaison à virgule flottante et d'autres architecture- étranges et merveilleux FP cas spécifiques.


Edit: Vous devez utiliser à la place de bounds.size lors du calcul contentSize visibleRect.size

.

Version Shorter:

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

Je ne sais pas si ce comportement est défini, mais presque toutes les sous-classes UIView ont l'origine de leur mis à bounds (0,0). UIScrollViews, cependant l'ensemble d'origine à contentOffset.

une petite solution plus générale serait:

 [scrollView convertRect:scrollView.bounds
                             toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;

Je ne pense pas que UIScrollView vous donne ce rectangle directement, mais je pense que vous avez tous les éléments nécessaires pour le calculer.

Une combinaison des limites, le contentOffset et le zoomScale devrait être tout ce que vous devez créer le rectangle que vous recherchez.

Swift 4.0:

Ma réponse adapte réponse de Trenskow à Swift 4.0:

let visible = scrollView.convert(scrollView.bounds, to: subView)

où la vue est scrollView du rouleau, et la vue est subView l'intérieur qui est zoomable <=> et contient tout le contenu à l'intérieur du rouleau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top