Reputation: 354
I have a UIScrollView with an UIImageView as the content. It displays fine, and scrolls fine. No problems there. The image is considerably wider than the screen, so I want to be able to "auto center" a specific portion (coordinates) of the image within the scrollview.
Here is where I'm stuck, though. The desired centering location will dynamically change based on the use of the application, so I need to be able to configure it so that a desired coordinate of the image view (x,y) is centered automatically within the scrollview when loaded. It doesn't have to autoscroll/animate, it just needs to be there.
I've seen similar questions/answers for centering content when gestures/zooming are being used, but neither are employed here. Just scrolling. I just need to be able to have a set portion of the image be centered within the scrollview when it first loads.
I hope I've made sense. Thanks for your time.
Upvotes: 3
Views: 8629
Reputation: 9847
Simply setting its position in the scrollview works. For example:
- (void)centreImageView
{
CGRect bounds = self.bounds;
CGSize contentSize = self.contentSize;
CGFloat offsetX = MAX(0, (bounds.size.width - contentSize.width) * 0.5f);
CGFloat offsetY = MAX(0, (bounds.size.height - contentSize.height) * 0.5f);
_myContentView.center = CGPointMake(contentSize.width * 0.5 + offsetX, contentSize.height * 0.5 + offsetY);
}
And call that in your initialisation and also from - (void)scrollViewDidZoom:(UIScrollView *)scrollView
if you are zooming.
Upvotes: 1
Reputation: 43330
I'm on an iPhone right now, so excuse me if this code is a little funky, as I can't remember exactly if the center property is available without calling size.center first...
CGPoint centerOffset = CGPointMake(0, [scrollView contentSize].(size).center);
[scrollView setContentOffset: centerOffset animated: YES]; // (or No, depends on you)
Upvotes: 5
Reputation: 13343
After a few days of researching this issue I came up with a simple solution using the ScrollView property - contentInset. This will always center the image, even while zooming (if you follow all instructions).
- (void)centerImage
{
if (!self.image) return;
CGFloat imageScaleWidth = self.image.size.width * self.scrollView.zoomScale;
CGFloat imageScaleHeight = self.image.size.height * self.scrollView.zoomScale;
CGFloat hOffset = (self.frame.size.width - imageScaleWidth) * 0.5f;
CGFloat vOffset = (self.frame.size.height - imageScaleHeight) * 0.5f;
if (hOffset < 0) hOffset = 0;
if (vOffset < 0) vOffset = 0;
self.scrollView.contentInset = UIEdgeInsetsMake(vOffset, hOffset, 0, 0);
}
Call this method in the ScrollView delegate:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
[self centerImage];
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
[self centerImage];
}
AND when you layout your SubViews:
- (void)layoutScrollView
{
if (!self.image) return;
CGFloat heightScale = self.frame.size.height / self.image.size.height;
CGFloat widthScale = self.frame.size.width / self.image.size.width;
CGFloat scale = MIN(widthScale, heightScale);
self.scrollView.minimumZoomScale = scale;
self.scrollView.maximumZoomScale = MAX(1.0f ,scale * 2.0f);
[self.scrollView setZoomScale:self.scrollView.minimumZoomScale animated:NO];
[self centerImage];
}
Upvotes: 2
Reputation: 2161
Not sure if this is what you are looking for but I just thought I would put it out there, does this method help?
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [scroller frame].size.height / scale;
zoomRect.size.width = [scroller frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
Or this one?
- (CGRect)zoomRectForScale:(float)scale withOrigin:(CGPoint)origin {
CGRect zoomRect;
// the zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible, the size of the rect grows.
zoomRect.size.height = [scroller frame].size.height / scale;
zoomRect.size.width = [scroller frame].size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = origin.x;
zoomRect.origin.y = origin.y;
return zoomRect;
}
Note: I didn't write these, they are from sample code provided by Apple but I use them occasionally and I thought of them when I saw your question.
Upvotes: 0