How can I go about finding out the rect (CGRect) of the content of a displayed view that is actually visible on screen.
myScrollView.bounds
Swift 4.0:
My answer adapts Trenskow's answer to Swift 4.0:
let visible = scrollView.convert(scrollView.bounds, to: subView)
where scrollView
is the view of the scroll, and subView
is the view inside scrollView
which is zoomable and contains all the contents inside the scroll.
Answering my own question, mostly thanks to Jim Dovey's answer, which didn't quite do the trick, but gave me the base for my answer:
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;
The main difference is that the size of the visibleRect ought to be scrollView.bounds.size
, rather than scrollView.contentSize
which is the size of the content view. Also simplified the math a bit, and didn't quite see the use for the isless()
which would break the code whenever it's greater.
a little more general solution would be:
[scrollView convertRect:scrollView.bounds
toView:[scrollView.delegate viewForZoomingInScrollView:scrollView]];
Shorter version:
CGRect visibleRect = CGRectApplyAffineTransform(scrollView.bounds, CGAffineTransformMakeScale(1.0 / scrollView.zoomScale, 1.0 / scrollView.zoomScale));
I'm not sure if this is defined behavior, but almost all UIView subclasses have the origin of their bounds
set to (0,0). UIScrollViews, however, have the origin set to contentOffset
.
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = scrollView.frame.size;
I don't think that a UIScrollView gives you that rectangle directly, but I think you have all the necessary items to calculate it.
A combination of the bounds, the contentOffset and the zoomScale should be all you need to create the rectangle you are looking for.