简体   繁体   中英

How can I zoom a UIScrollview to a fixed point?

I am creating a control for showing the timeline. Initially , it should show the year. When zooming in and the zoomScale reached a specific value, it will show the value of the individual months, and In the next zoom level, it should show the real values for the individual days.

I have creatd a scrollview and added the layers (for showing the month/year values) to this. After overriding the pinch guesture, I am able to do the zooming ( Normal UIScrollview zooming ). But I need to zoom it to a particular point. ie, Suppose i am zooming January, I need to keep it in the same position( for creating an effect like moving inside of January ). Any suggestions to achieve this?

Is my way is currect? else please help me to start this.

Use This bellow method for your requirement,

- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated

just call this above method with your selected frame or point , like if select January then just take the point ( position) of january button or view and just call above method with that frame..

for more information see this link UIScrollView_Class

i hope this helpful to you...

Here's what it looks like:

@implementation UIScrollView (ZoomToPoint)

- (void)zoomToPoint:(CGPoint)zoomPoint withScale: (CGFloat)scale animated: (BOOL)animated
{
    //Normalize current content size back to content scale of 1.0f
    CGSize contentSize;
    contentSize.width = (self.contentSize.width / self.zoomScale);
    contentSize.height = (self.contentSize.height / self.zoomScale);

    //translate the zoom point to relative to the content rect
    zoomPoint.x = (zoomPoint.x / self.bounds.size.width) * contentSize.width;
    zoomPoint.y = (zoomPoint.y / self.bounds.size.height) * contentSize.height;

    //derive the size of the region to zoom to
    CGSize zoomSize;
    zoomSize.width = self.bounds.size.width / scale;
    zoomSize.height = self.bounds.size.height / scale;

    //offset the zoom rect so the actual zoom point is in the middle of the rectangle
    CGRect zoomRect;
    zoomRect.origin.x = zoomPoint.x - zoomSize.width / 2.0f;
    zoomRect.origin.y = zoomPoint.y - zoomSize.height / 2.0f;
    zoomRect.size.width = zoomSize.width;
    zoomRect.size.height = zoomSize.height;

    //apply the resize
    [self zoomToRect: zoomRect animated: animated];
}

@end

Looking at it, it should be pretty straightforward to figure out how it works. If you see anything wrong with it, let me know in the comments.
Thanks :)

source: http://www.tim-oliver.com/2012/01/14/zooming-to-a-point-in-uiscrollview/

I had same problem,
I was having a world map image, & i wanted to zoom the map to certain location, India
This is how i fixed it.
I found out the position of India, in terms of CGRect(X,Y) [CGRect(500,300)]
& following code in DidLoad

    [self.scrollViewForMap setZoomScale:2.0 animated:YES]; //for zooming
    _scrollViewForMap.contentOffset = CGPointMake(500,300); //for location

This solved my problem. :)

- (void)pinchDetected:(UIPinchGestureRecognizer *)gestureRecognizer {

if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
    // Reset the last scale, necessary if there are multiple objects with different scales
    lastScale = [gestureRecognizer scale];
}

if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
    [gestureRecognizer state] == UIGestureRecognizerStateChanged) {

    CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];

    // Constants to adjust the max/min values of zoom
    const CGFloat kMaxScale = 2.2;
    const CGFloat kMinScale = 0.64;

    CGFloat newScale = 1 -  (lastScale - [gestureRecognizer scale]);
    newScale = MIN(newScale, kMaxScale / currentScale);
    newScale = MAX(newScale, kMinScale / currentScale);
    CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
    [gestureRecognizer view].transform = transform;

    [gestureRecognizer setScale:1.0];

    lastScale = [gestureRecognizer scale];  // Store the previous scale factor for the next pinch gesture call
}
}

What worked for me ( Swift 4 ):

func zoomIn(with gestureRecognizer: UIGestureRecognizer?) {
    guard let location = gestureRecognizer?.location(in: gestureRecognizer?.view)

    let rect = CGRect(x: location.x, y: location.y, width: 0, height: 0)
    scrollView.zoom(to: rect, animated: true)
}

Or in other words creating a CGRect with zero width and height will cause the UIScrollView to zoom to the rects origin at maximumZoomScale

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM