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

查看:148
本文介绍了将可缩放图像保留在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.

我试图重新计算并重新设置 UIScrollView contentSize 和图片视图的大小 scrollViewDidEndZooming 方法:

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];
}

请注意,我在设置插图时使用动画,否则图像会跳转添加插入时在scrollview内部。通过动画,它可以滑动到中心。我正在使用 UIView beginAnimation commitAnimation 而不是动画阻止,因为我需要在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天全站免登陆