UIImageView保持宽高比,但适应宽度

20

我有一个固定宽度和高度的UIImageView。我不想改变UIImageView的框架。我想让它容纳一张保持长宽比的图片,并适应宽度,让图像过高或者过短以适应UIImageView的框架,就像这样:

UIImageView frame

红色是UIImageView的框架。 灰色是实际显示的图像。

4个回答

33

我认为最好的方法是调整imageView的显示模式(Aspect Fill,Aspect Width等),这取决于图像宽高比。

if image.width > image.height {
    imageView.contentMode = UIViewContentModeScaleAspectFit
    //since the width > height we may fit it and we'll have bands on top/bottom
} else {
  imageView.contentMode = UIViewContentModeScaleAspectFill
  //width < height we fill it until width is taken up and clipped on top/bottom
}

UIViewContentModeScaleAspectFit

将内容按照其原有宽高比缩放以适应视图的大小。视图剩余区域为透明。

UIViewContentModeScaleAspectFill

将内容按照其原有宽高比缩放以填充视图的大小。一些内容可能会被裁剪以填充视图边界。

我没有测试过,但凭直觉这似乎是正确的。


太棒了,我会试着玩一下。好主意。 - SirRupertIII
我正在处理 MPMediaItemArtwork,怎么做? - Jared Chu
1
此解决方案不考虑视图的形状,只考虑图像的形状。此解决方案仅适用于视图为正方形的情况。对于宽图像,如果视图是宽而瘦的,则会按比例适应图像,而实际上应该按比例填充。 - Andy

4

我认为您需要将图像的宽高比与UIImageView本身的宽高比进行比较:

private func updateUI() {
    guard let image = image else { return }
    let viewAspectRatio = self.bounds.width / self.bounds.height
    let imageAspectRatio = image.size.width / image.size.height
    if viewAspectRatio > imageAspectRatio {
        self.contentMode = .scaleAspectFill
    } else {
        self.contentMode = .scaleAspectFit
    }
}

override var image: UIImage? { didSet { updateUI() }}

override func layoutSubviews() {
    super.layoutSubviews()
    updateUI()
}

注意:这是等比缩放的宽度适应方式。

这个能用来将图像的宽高比设置为16:9吗?如果可以,最好的方法是什么? - Luke Irvin
问题是关于保持图像的原始纵横比,但在可能与图像不同的纵横比视图中显示图像。如果您想强制图像的纵横比,可以使用约束。例如,在界面构建器中,您可以设置UIImageView的纵横比。这就是您所问的吗? - Andy

3

Swift 5.1 iOS 13

因为我的问题出现在集合视图的标题单元格上,所以这是适用于我的解决方法:

if headerCell!.imageView.frame.width > headerCell!.imageView.frame.height {
    headerCell!.imageView.contentMode = .scaleAspectFit
    //since the width > height we may fit it and we'll have bands on top/bottom
} else {
     headerCell!.imageView.contentMode = .scaleAspectFill
     //width < height we fill it until width is taken up and clipped on top/bottom
}

1
对于我的情况,解决方案是根据图像高度和宽度的比率是否大于imageView的比率来设置UIImageViewcontentMode
func setupImageViewContentMode() {
    if let image = imageView.image, image.size.height / image.size.width > imageView.frame.height / imageView.frame.width {
        imageView.contentMode = .scaleAspectFit
    } else {
        imageView.contentMode = .scaleAspectFill
    }
}

此外,请注意您必须根据当前布局设置此内容,因此在layoutSubviews()viewDidLayoutSubviews()中调用此方法,在从后端加载图像或任何需要它的地方之后进行操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接