Tom,
Your question is a little old, but I came up with a solution for this, so I decided that I would answer in case it helps you or anyone else. The main trick is to reset the scroll in the view zoomScaleto 1, and then adjust minimumZoomScaleand maximumZoomScaleso that the user can zoom in and out as expected.
In my implementation, I have subclassed UIScrollViewand appointed him my delegate. In my subclass, I implement two delegate methods that you need to scale (shown below). contentView is a property that I added to my subclass UIScrollViewto give it a view that actually displays the content.
, init (kMinimumZoomScale kMaximumZoomScale #define ):
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.autoresizesSubviews = YES;
self.showsVerticalScrollIndicator = YES;
self.showsHorizontalScrollIndicator = NO;
self.bouncesZoom = YES;
self.alwaysBounceVertical = YES;
self.delegate = self;
self.minimumZoomScale = kMinimumZoomScale;
self.maximumZoomScale = kMaximumZoomScale;
}
return self;
}
UIScrollView . ContentView zoomScale, , . drawRect .
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)aScrollView {
return contentView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale:(float)scale {
CGFloat oldZoomScale = contentView.zoomScale;
CGSize size = self.bounds.size;
CGPoint contentCenter = self.contentOffset;
contentCenter.x += size.width / (oldZoomScale * scale) / 2;
contentCenter.y += size.height / (oldZoomScale * scale) / 2;
CGFloat newZoomScale = scale * oldZoomScale;
newZoomScale = MAX(newZoomScale, kMinimumZoomscale);
newZoomScale = MIN(newZoomScale, kMaximumZoomscale);
self.zoomScale = 1.0;
self.minimumZoomScale = kMinimumZoomScale / newZoomScale;
self.maximumZoomScale = kMaximumZoomScale / newZoomScale;
contentView.zoomScale = newZoomScale;
CGRect newContentSize = [contentView sizeThatFits];
contentView.frame = CGRectMake(0, 0, newContentSize.width, newContentSize.height);
self.contentSize = newContentSize;
CGPoint newContentOffset = CGPointMake(contentCenter.x - size.width / newZoomScale / 2,
contentCenter.y - size.height / newZoomScale / 2);
newContentOffset.x = MIN(newContentOffset.x, newContentSize.width - size.width);
newContentOffset.x = MAX(0, newContentOffset.x);
newContentOffset.y = MIN(newContentOffset.y, newContentSize.height - .size.height);
newContentOffset.y = MAX(0, newContentOffset.y);
[self setContentOffset:newContentOffset animated:NO];
}