Alede
Alede

Reputation: 381

How to center image in a uiimageview/uiscrollview (pre and post zooming)

I am trying to center an image (with respect to the iphone screen) such that when the view is loaded the image is center width/height... In my case my view is loaded at pixel points 0,0 of the image itself and if I zoom out the image appears in the top left corner as opposed to mid-center of the screen/view. Here is what I have so far:

UIImage *image = [UIImage imageNamed: @"t.bmp"];
self.view.backgroundColor = [UIColor blackColor];
self.mi.frame = CGRectMake(0, 0, image.size.width, image.size.height);
self.mi.contentMode = (UIViewContentModeCenter);
self.mi.backgroundColor = [UIColor blackColor];
[self.mi setImage:image];

/* Draw a line here!!
UIGraphicsBeginImageContext(self.mi.frame.size);
[self.mi.image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 20.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, 0,0);
CGContextAddLineToPoint(context, 200, 200);    
CGContextMoveToPoint(context, 200,0);
CGContextAddLineToPoint(context, 0, 200);
CGContextStrokePath(context);
self.mi.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
*/

self.expimg.maximumZoomScale = 2.0;
self.expimg.minimumZoomScale = 0.1;
self.expimg.clipsToBounds = YES;
self.expimg.delegate = self;
[self.expimg setContentSize:self.mi.frame.size];

[self.expimg addSubview: self.mi];
[self.view addSubview: self.expimg];

Thanks!

Edit: mi is a UIImageView and expimg is a UIScrollView (used interface builder). Also, viewForZoomingInScrollView is defined.

Upvotes: 1

Views: 9450

Answers (3)

Heo Đất Hades
Heo Đất Hades

Reputation: 1633

Step 1: You create an image view property then init it at viewDidLoad and add to scrollView:

self.pictureImage = [[UIImageView alloc]initWithImage:self.picture];
[_scrollView addSubview:_pictureImage];
self.pictureImage.alpha = 0;
_scrollView.delegate = self;

Step 2: Create adjustZoomScale function to get minimum scale

- (CGFloat)adjustZoomScale{
CGFloat scale = self.scrollView.bounds.size.width / self.pictureImage.bounds.size.width;
CGFloat h = scale * self.pictureImage.bounds.size.height;
if (h > self.scrollView.bounds.size.height) {
    scale = self.scrollView.bounds.size.height / self.pictureImage.bounds.size.height;
}
return scale;
}

Step 3: Because frame of scroll view will be updated at viewDidAppear so we need to adjust zoom scale here. And set alpha to make image appear smoother:

- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear: animated];
_scrollView.maximumZoomScale = 1.0;
_scrollView.minimumZoomScale = [self adjustZoomScale];
[_scrollView setZoomScale:_scrollView.minimumZoomScale];
self.pictureImage.alpha = 1;
}

Step 4: Implement viewForZoomingInScrollView (scroll delegate method) and return image view

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return self.pictureImage;
}

Step 5: Implement scrollViewDidZoom (scroll delegate method) and adjust point for image view

- (void)scrollViewDidZoom: (UIScrollView*) scrollView {
CGSize boundsSize = scrollView.bounds.size;
CGRect contentsFrame = _pictureImage.frame;

if (contentsFrame.size.width < boundsSize.width) {
    contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0;
} else {
    contentsFrame.origin.x = 0.0;
}

if (contentsFrame.size.height < boundsSize.height) {
    contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0;
} else {
    contentsFrame.origin.y = 0.0;
}
_pictureImage.frame = contentsFrame;
}

Thank shawhu at this post for point adjusting for image view while zooming

Upvotes: 1

KETAN
KETAN

Reputation: 481

[scrollView zoomToRect:CGRectMake(x, y, width, height) animated:YES]; will work for you... Where rect should have those center coordinates as origin.

Upvotes: -1

Katfish
Katfish

Reputation: 698

You should be able to do this by adjusting the position and size of the image and scroll view on initial load, and as zoom levels change. Make a method that is called on viewDidLoad, and again on the UIScrollViewDelegate method scrollViewDidZoom:.

Something like this should work (where imageView and scrollView are class attributes):

- (void)centerImage {

    CGSize screenSize = CGSizeMake(320, 480);

    CGSize imageSize = imageView.frame.size;
    imageSize.width = imageSize.width * scrollView.zoomScale;
    imageSize.height = imageSize.height * scrollView.zoomScale;
    CGSize scrollSize = scrollView.frame.size;

    CGFloat centerX;
    CGFloat centerY;
    CGFloat left;
    CGFloat top;

    if (imageSize.width > screenSize.width) {
        scrollSize.width = imageSize.width;
        centerX = imageSize.width/2;
        left = 0;
    } else {
        scrollSize.width = screenSize.width;
        centerX = screenSize.width/2;
        left = centerX - imageSize.width/2;
    }

    if (imageSize.height > screenSize.height) {
        scrollSize.height = imageSize.height;
        centerY = imageSize.height/2;
        top = 0;
    } else {
        scrollSize.height = screenSize.height;
        centerY = screenSize.width/2;
        top = centerY - imageSize.height/2;
    }

    CGRect scrollFrame = scrollView.frame;
    scrollFrame.size = scrollSize;
    scrollView.frame = scrollFrame;

    CGRect imageFrame = imageView.frame;
    imageFrame.origin = CGPointMake(left, top);

    scrollView.contentOffset = CGPointMake(centerX-(imageSize.width/2), centerY-(imageSize.height/2));

}

I have not tested this, so some of my math could be wrong. Either way, it will hopefully give you a good idea of what to do.

Upvotes: 1

Related Questions