汤姆,
你的问题是有点老了,但我想出了一个解决方案,所以我想我会放在一个答案的情况下,它可以帮助你或其他人。基本技巧是将滚动视图的zoomScale
重置为1,然后调整minimumZoomScale
和maximumZoomScale
,以便用户仍然可以按预期放大和缩小。
在我的实现中,我已将子类UIScrollView
设置为它自己的代理。在我的子类中,我实现了缩放所需的两个委托方法(如下所示)。 contentView是我添加到我的UIScrollView
子类中的一个属性,用于为其提供实际显示内容的视图。
所以,我的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;
// Figure out where the scroll view was centered so that we can
// fix up its offset after adjusting the scaling
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);
// Set the scroll view's zoom scale back to 1 and adjust its minimum and maximum
// to allow the expected amount of zooming.
self.zoomScale = 1.0;
self.minimumZoomScale = kMinimumZoomScale/newZoomScale;
self.maximumZoomScale = kMaximumZoomScale/newZoomScale;
// Tell the contentView about its new scale. My contentView.zoomScale setter method
// calls setNeedsDisplay, but you could also call it here
contentView.zoomScale = newZoomScale;
// My ContentView class overrides sizeThatFits to give its expected size with
// zoomScale taken into account
CGRect newContentSize = [contentView sizeThatFits];
// update the content view's frame and the scroll view's contentSize with the new size
contentView.frame = CGRectMake(0, 0, newContentSize.width, newContentSize.height);
self.contentSize = newContentSize;
// Figure out the new contentOffset so that the contentView doesn't appear to move
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];
}
非常感谢您的解决方案!这解决了[我的问题](http://stackoverflow.com/questions/3970988/how-to-draw-on-a-non-transformed-context-while-zoomed-in-a- catiledlayer)。你可以在那里留下一个链接到你的答案,所以我可以给你适当的信用来回答它? – TinkerTank 2010-10-21 14:08:37
如果使用此方法缩放CATiledLayer,则在调用setNeedsDisplay之前需要清除tile-cache。清除CATiledLayerCache的解决方案可在[here](http:// stackoverflow。com/questions/1274680/clear-catiledlayers-cache-when-changing-images) – TinkerTank 2010-10-21 14:12:15
你能解释一下contentSize的属性以及它如何设置以及它实际是什么。谢谢 – BDGapps 2012-03-06 03:32:40