我在 UIScrollView
中有一个 UIView
。每当 UIScrollView
缩放更改时,我想在新的缩放级别重绘整个 UIView
。
在 iOS < 3.2 中,我通过调整 UIScrollView
中的 UIView
的大小来实现这一点,使其成为新的大小,然后将转换设置回 Identity,所以它不会尝试进一步调整它的大小。但是,对于 iOS >= 3.2,更改标识也会更改 UIScrollView
的 zoomScale 属性。
结果是,每当我缩放(比如 2 倍)时,我都会将嵌入的 UIView
调整为合适的大小,然后重绘它。但是现在(因为我将转换重置为 Identity),UIScrollView
再次认为它是 zoomScale 1,而不是 zoomScale 2。所以如果我将 maxZoomScale 设置为 2,它仍会尝试进一步缩放, 这是错误的。
我考虑过使用 CATiledLayer
,但我认为这对我来说还不够,因为我想在每次缩放后重绘,而不仅仅是像它尝试做的那样在某些缩放阈值处重绘。
有人知道如何在缩放时正确重绘 UIView
吗?
最佳答案
汤姆,
你的问题有点老了,但我想出了一个解决方案,所以我想我会给出一个答案,以防它对你或其他人有帮助。基本技巧是将 ScrollView 的 zoomScale
重置为 1,然后调整 minimumZoomScale
和 maximumZoomScale
以便用户仍然可以放大和按预期输出。
在我的实现中,我将 UIScrollView
子类化并将其设置为自己的委托(delegate)。在我的子类中,我实现了缩放所需的两个委托(delegate)方法(如下所示)。 contentView 是我添加到我的 UIScrollView
子类中的一个属性,以便为其提供实际显示内容的 View 。
所以,我的 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
委托(delegate)方法来缩放。我的 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];
}
关于iphone - 每次缩放后重绘 UIScrollView 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3313947/