使用自动布局缩放 UIImageView 的 UIScrollView

2024-02-27

考虑一个UIScrollView有一个子视图。子视图是一个UIImageView具有以下尺寸限制:

  • 它的高度必须等于UIScrollView.
  • 它的宽度必须是与图像的高度成比例缩放的图像的宽度UIImageView.

预计宽度UIImageView将大于 UIScrollView 的宽度,因此需要滚动。

图像可能会在viewDidLoad(如果已缓存)或异步。

如何使用自动布局来实现上述内容,并尽可能多地使用界面构建器?

到目前为止我做了什么

基于此answer https://stackoverflow.com/a/13548039/143378我这样配置我的笔尖:

  • The UIScrollView固定在其超级视图的边缘。
  • The UIImageView被固定在边缘UIScrollView.
  • The UIImageView有一个占位符固有大小(以避免可滚动内容大小不明确 error)

正如预期的那样,结果是UIImageView的大小为UIImage,以及UIScrollView水平和垂直滚动(因为图像大于UIScrollView).

然后我尝试了各种不起作用的方法:

  • 加载图像后手动设置框架UIImageView.
  • 为 UIImageView 的宽度添加约束,并在图像加载后修改其值。这使得图像更大(?!)。
  • Set zoomScale图像加载后。没有明显的效果。

没有自动布局

以下代码完全按照我想要的方式执行,尽管没有自动布局或界面生成器。

- (void)viewDidLoad
{
    {
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.view addSubview:scrollView];
        self.scrollView = scrollView;
    }

    {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self.scrollView addSubview:imageView];
        self.scrollView.contentSize = imageView.frame.size;
        self.imageView = imageView;
    }
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self layoutStripImageView];
}

- (void)layoutStripImageView
{ // Also called when the image finishes loading
    UIImage *image = self.imageView.image;
    if (! image) return;

    const CGSize imageSize = image.size;
    const CGFloat vh = self.scrollView.frame.size.height;
    const CGFloat scale = vh / imageSize.height;
    const CGFloat vw = imageSize.width * scale;

    CGSize imageViewSize = CGSizeMake(vw, vh);
    self.imageView.frame = CGRectMake(0, 0, imageViewSize.width, imageViewSize.height);
    self.scrollView.contentSize = imageViewSize;
}

我正在努力转向自动布局,但这并不容易。


在自动布局机制下,理想情况下 UIScrollView内容大小仅由约束决定,而不是在代码中明确设置。

所以在你的情况下:

  • 创建约束以将子视图固定到UIScrollView.约束必须确保子视图和滚动视图之间的边距为 0。我看到您已经尝试过此操作。

  • 为子视图创建高度和宽度约束。否则,固有尺寸UIImageView决定了它的高度和宽度。在设计时,这个大小只是一个占位符,以使 Interface Builder 满意。在运行时,它将被设置为实际的图像大小,但这不是您想要的。

  • During viewDidLayoutSubviews,将约束更新为实际内容大小。您可以通过更改直接执行此操作constant高度和宽度约束的属性,或调用setNeedsUpdateConstraints并压倒一切updateConstraints做同样的事情。

这确保了系统可以导出contentSize仅仅来自于限制。

我已经完成了上述操作,它可以在 iOS 6 和 7 上可靠地运行UIScrollView和一个自定义子视图,所以它应该适用于UIImageView也。特别是如果您不将子视图固定到滚动视图,则在 iOS 6 中缩放将会变得不稳定。

您还可以尝试创建直接引用滚动视图的高度和宽度的倍数的高度和宽度约束,但我还没有尝试过这种其他方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用自动布局缩放 UIImageView 的 UIScrollView 的相关文章

随机推荐