Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the zoomed frame of UIScrollView relative to original size

I have a UIScrollView and added a UIView inside it, when I zoom it, is it possible to get the CGRect of the zoomed frame in relation to the original frame?

E.g. i have 800x600 frame, then i zoomed to {{50, 60}, {100, 100}} is it possible to programmatically get the zoomed frame?

like image 714
Manny Avatar asked Oct 04 '10 08:10

Manny


People also ask

How do i Zoom an image in UIScrollView?

To kick off this UIScrollView tutorial, you’ll set up a scroll view that lets the user pan and zoom an image. Open Main.storyboard and drag a Scroll view from the Object Library onto the document outline, right below View on the Zoomed Photo View Controller scene. Then, move Image View inside your newly-added Scroll View.

How to size the Scroll View’s frame with auto layout?

To size the scroll view’s frame with Auto Layout, you need to either make the constraints regarding the width and height of the scroll view explicit, or you must tie the edges of the scroll view to views outside of its own subtree. You can read more in this technical note from Apple.

How does auto layout work with UIScrollView?

Note: In general, Auto Layout considers the top, left, bottom and right edges of a view to be the visible edges. However, UIScrollView scrolls its content by changing the origin of its bounds.

What are the visible edges of a scroll view?

Note: In general, Auto Layout considers the top, left, bottom and right edges of a view to be the visible edges. However, UIScrollView scrolls its content by changing the origin of its bounds. To make this work with Auto Layout, the edges within a scroll view actually refer to the edges of its Content view.


Video Answer


2 Answers

I usually use the following method (added to the custom UIScrollView category):

- (CGRect) visibleRect{
    CGRect visibleRect;

    visibleRect.origin = self.contentOffset;
    visibleRect.size = self.bounds.size;

    visibleRect.origin.x /= self.zoomScale;
    visibleRect.origin.y /= self.zoomScale;
    visibleRect.size.width /= self.zoomScale;
    visibleRect.size.height /= self.zoomScale;
    return visibleRect;
}
like image 171
Vladimir Avatar answered Oct 21 '22 11:10

Vladimir


The problem with @Vladimir solution is that it displays visibleRect wrong if viewForZoom is smaller than ScrollView bounds. So I came up with this solution.

- (CGRect) zoomedFrame{
    CGRect zoomedFrame;

    zoomedFrame.origin = self.contentOffset;
    zoomedFrame.origin.x -= zoomingView.frame.origin.x;
    zoomedFrame.origin.y -= zoomingView.frame.origin.y;
    zoomedFrame.size = self.contentSize;
    return zoomedFrame;
}

zoomingView is a view that returns viewForZoomingInScrollView: method.
bounds are bounds of scrollView.


So there are two cases:

  1. When the zoomingView is smaller than bounds, contentOffset reflect not the top-left corner of content view, but some strange shift of content view relative to the center of bounds. And zoomingView.frame.origin has normal values as if zoomingView were in the center of bounds. (this happens if you try to shrink the zoomingView more than minimulScale)

  2. When the zoomingView is bigget than bounds, zoomingView.frame.origin has strange values like this:

    {-6.15367e-06, 3.98168e-06}

    And contentOffset shows what it should.


So all that compensate each other as I showed in my code.

like image 37
DanSkeel Avatar answered Oct 21 '22 10:10

DanSkeel