返回

如何调整 UIImageView 中图片大小而不改变边框?

IOS

如何调整 UIImageView 中图片的大小而不改变边框大小?

在 iOS 开发中,用 UIImageView 展示图片是家常便饭。但有时,我们需要图片在 UIImageView 中自适应大小,以应对不同的屏幕尺寸或布局要求,同时又不改变 UIImageView 本身的大小。说白了,我们希望图片在 UIImageView 的边框内自由呼吸,而不是被强制拉伸或压缩。

UIImageView 的 contentMode 属性

问题的根源在于 UIImageView 的 contentMode 属性。这个属性决定了图片在 UIImageView 中的显示方式。默认情况下,contentMode 被设置为 .scaleToFill,这意味着图片会被无情地拉伸或压缩,以填满整个 UIImageView,而图片的原始比例?谁在乎!

你遇到的问题是,当你使用自定义方法调整图片大小时,图片的尺寸确实变了,但 UIImageView 的 contentMode 仍然固执地保持着 .scaleToFill,于是调整后的图片再次被拉伸,填满整个 UIImageView,你的努力付诸东流。

解决方案:调整 contentMode

想要解决这个问题,我们需要改变 UIImageView 的 contentMode 属性。contentMode 有很多可选值,其中 .scaleAspectFit.scaleAspectFill 能够在保持图片原始比例的同时,调整图片大小。

  • .scaleAspectFit: 图片会被调整到完全包含在 UIImageView 中,并保持原始比例。如果图片的比例与 UIImageView 不一致,图片周围会出现空白区域,就像图片在 UIImageView 的怀抱中找到了一个舒适的姿势。
  • .scaleAspectFill: 图片会被调整到填满整个 UIImageView,并保持原始比例。如果图片的比例与 UIImageView 不一致,图片超出部分会被无情地裁剪,就像图片试图挣脱 UIImageView 的束缚,却被无情地剪掉了翅膀。

选择哪种 contentMode 取决于你的具体需求。如果需要完整显示图片内容,选择 .scaleAspectFit,给图片更多呼吸的空间;如果需要图片填满整个 UIImageView,选择 .scaleAspectFill,让图片充满整个舞台。

代码示例:.scaleAspectFit

以下是使用 .scaleAspectFit 修改后的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    let imageView = UIImageView()
    view.addSubview(imageView)
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.layer.borderWidth = 5
    imageView.layer.borderColor = UIColor.green.cgColor
    // 设置 contentMode 为 .scaleAspectFit
    imageView.contentMode = .scaleAspectFit 
    NSLayoutConstraint.activate([
        imageView.heightAnchor.constraint(equalToConstant: 200),
        imageView.widthAnchor.constraint(equalToConstant: 200),
        imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0),
        imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0),
    ])
    let image = UIImage(named: "yourImageName")
    imageView.image = image
}

现在,图片会在保持原始比例的情况下调整大小,并在 UIImageView 的绿色边框内显示,不会再被强制拉伸或压缩,实现了你在 UIImageView 中给图片自由呼吸的愿望。

代码示例:.scaleAspectFill

以下是使用 .scaleAspectFill 修改后的代码:

override func viewDidLoad() {
    super.viewDidLoad()
    let imageView = UIImageView()
    view.addSubview(imageView)
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.layer.borderWidth = 5
    imageView.layer.borderColor = UIColor.green.cgColor
    // 设置 contentMode 为 .scaleAspectFill
    imageView.contentMode = .scaleAspectFill 
    NSLayoutConstraint.activate([
        imageView.heightAnchor.constraint(equalToConstant: 200),
        imageView.widthAnchor.constraint(equalToConstant: 200),
        imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0),
        imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0),
    ])
    let image = UIImage(named: "yourImageName")
    imageView.image = image
}

现在,图片会在保持原始比例的情况下调整大小,填满整个 UIImageView 的绿色边框,实现了你在 UIImageView 中让图片占据整个舞台的愿望。

常见问题

1. 除了 .scaleAspectFit 和 .scaleAspectFill,还有哪些常用的 contentMode?

除了上面提到的两种,还有 .center.top.bottom.left.right.topLeft.topRight.bottomLeft.bottomRight 等,它们分别控制图片在 UIImageView 中的对齐方式。

2. 如何判断图片是否被裁剪?

你可以通过比较图片的原始尺寸和 UIImageView 的尺寸来判断。如果图片的尺寸大于 UIImageView 的尺寸,则图片会被裁剪。

3. 如何获取图片被裁剪后的尺寸?

你可以通过 UIImageView 的 contentClippingRect 属性获取图片被裁剪后的尺寸。

4. 如何实现更复杂的图片调整效果?

你可以使用 Core Image 或第三方库来实现更复杂的图片调整效果,例如:圆角、阴影、滤镜等。

5. 如何提高图片加载效率?

你可以使用缓存机制来提高图片加载效率,例如:SDWebImage、Kingfisher 等第三方库。