将可缩放图像保持在 UIScrollView 的中心 [英] Keep zoomable image in center of UIScrollView

查看:38
本文介绍了将可缩放图像保持在 UIScrollView 的中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 iPhone 应用程序中,我需要为用户提供缩放/平移屏幕上的大图像的能力.这很简单:我使用 UIScrollView,设置最大/最小比例因子和缩放/平移按预期工作.这就是事情变得有趣的地方.该图像是从服务器接收的动态图像.它可以有任何尺寸.当图像首次加载时,它会缩小(如果需要)以完全适合 UIScrollView 并在滚动视图中居中 - 屏幕截图如下:

In my iPhone app, I need to provide the user with an ability to zoom/pan a large-ish image on the screen. This is quite simple: I use UIScrollView, set max/min scale factors and zooming/panning works as expected. Here's where things get interesting. The image is a dynamic one, received from a server. It can have any dimensions. When the image first loads, it's scaled down (if needed) to fit completely into the UIScrollView and is centered in the scroll view - the screenshot is below:

由于图像的比例与滚动视图的比例不同,因此在图像的上方和下方添加了空白区域,以使图像居中.但是,当我开始缩放图像时,实际图像变得足够大以填充整个滚动视图视口,因此不再需要顶部/底部的白色填充,但是它们仍然存在,从这个屏幕截图中可以看出:

Because the proportions of the image are different from those of the scroll view, there's white space added above and below the image so that the image is centered. However when I start zooming the image, the actual image becomes large enough to fill the whole of the scrollview viewport, therefore white paddings at top/bottom are not needed anymore, however they remain there, as can be seen from this screenshot:

我相信这是因为包含图像的 UIImageView 会自动调整大小以填充整个 UIScrollView,并且在缩放时,它会按比例增长.它的缩放模式设置为 Aspect Fit.UIScrollView 的委托 viewForZoomingInScrollView 只返回图像视图.

I believe this is due to the fact that the UIImageView containing the image is automatically sized to fill the whole of UIScrollView and when zoomed, it just grows proportionally. It has scale mode set to Aspect Fit. UIScrollView's delegate viewForZoomingInScrollView simply returns the image view.

我尝试在 scrollViewDidEndZooming 方法中重新计算和重新设置 UIScrollViewcontentSize 和图像视图的大小:

I attempted to recalculate and re-set UIScrollView, contentSize and image view's size in scrollViewDidEndZooming method:

CGSize imgViewSize = imageView.frame.size;
CGSize imageSize = imageView.image.size;

CGSize realImgSize;
if(imageSize.width / imageSize.height > imgViewSize.width / imgViewSize.height) {
    realImgSize = CGSizeMake(imgViewSize.width, imgViewSize.width / imageSize.width * imageSize.height);
}
else {
    realImgSize = CGSizeMake(imgViewSize.height / imageSize.height * imageSize.width, imgViewSize.height);
}
scrollView.contentSize = realImgSize;

CGRect fr = CGRectMake(0, 0, 0, 0);
fr.size = realImgSize;
imageView.frame = fr;

但这只会让事情变得更糟(边界仍然存在,但在垂直方向上平移不起作用).

However this was only making things worse (with bounds still being there but panning not working in the vertical direction).

有没有什么方法可以在不需要时自动减少空白,然后在放大期间再次增加?我怀疑这项工作需要在 scrollViewDidEndZooming 中完成,但我不太确定该代码需要是什么.

Is there any way to automatically reduce that whitespace as it becomes unneeded and then increment again during zoom-in? I suspect the work will need to be done in scrollViewDidEndZooming, but I'm not too sure what that code needs to be.

推荐答案

我想我明白了.解决方案是使用委托的 scrollViewDidEndZooming 方法,并在该方法中根据图像的大小设置 contentInset.该方法如下所示:

I think I got it. The solution is to use the scrollViewDidEndZooming method of the delegate and in that method set contentInset based on the size of the image. Here's what the method looks like:

- (void)scrollViewDidEndZooming:(UIScrollView *)aScrollView withView:(UIView *)view atScale:(float)scale {
    CGSize imgViewSize = imageView.frame.size;
    CGSize imageSize = imageView.image.size;

    CGSize realImgSize;
    if(imageSize.width / imageSize.height > imgViewSize.width / imgViewSize.height) {
        realImgSize = CGSizeMake(imgViewSize.width, imgViewSize.width / imageSize.width * imageSize.height);
    }
    else {
        realImgSize = CGSizeMake(imgViewSize.height / imageSize.height * imageSize.width, imgViewSize.height);
    }

    CGRect fr = CGRectMake(0, 0, 0, 0);
    fr.size = realImgSize;
    imageView.frame = fr;

    CGSize scrSize = scrollView.frame.size;
    float offx = (scrSize.width > realImgSize.width ? (scrSize.width - realImgSize.width) / 2 : 0);
    float offy = (scrSize.height > realImgSize.height ? (scrSize.height - realImgSize.height) / 2 : 0);
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.25];
    scrollView.contentInset = UIEdgeInsetsMake(offy, offx, offy, offx);
    [UIView commitAnimations];
}

请注意,我在设置插图时使用了动画,否则添加插图时图像会在滚动视图内跳转.随着动画它滑动到中心.我正在使用 UIView beginAnimationcommitAnimation 而不是动画块,因为我需要让应用程序在 iphone 3 上运行.

Note that I'm using animation on setting the inset, otherwise the image jumps inside the scrollview when the insets are added. With animation it slides to the center. I'm using UIView beginAnimation and commitAnimation instead of animation block, because I need to have the app run on iphone 3.

这篇关于将可缩放图像保持在 UIScrollView 的中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆