iphone - 每次缩放后重绘 UIScrollView 内容

标签 iphone uiscrollview ios

我在 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,然后调整 minimumZoomScalemaximumZoomScale 以便用户仍然可以放大和按预期输出。

在我的实现中,我将 UIScrollView 子类化并将其设置为自己的委托(delegate)。在我的子类中,我实现了缩放所需的两个委托(delegate)方法(如下所示)。 contentView 是我添加到我的 UIScrollView 子类中的一个属性,以便为其提供实际显示内容的 View 。

所以,我的 init 方法看起来像这样(kMinimumZoomScalekMaximumZoomScale#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/

相关文章:

iphone - NSURLConnection 发送数据两次

iphone - iOS:如何显示登录表单?

iphone - CLLocationManager 在发布时崩溃,但为什么呢?

ios - UIScrollView 错误偏移与自动布局

ios - 如何通过 FireBase 更新使用推送通知

iphone - iPhone 中的图像旋转问题

ios - UIScrollView 缩放到错误的点

objective-c - 如何控制嵌套的 ScrollView

ios - AVMutableAudioMixInputParameters 未正确应用于 AudioMiX

ios - swift 2 从解包变量中获取整数值