【问题标题】:AutoLayout: UIImageView and Aspect Fit content modeAutoLayout:UIImageView 和 Aspect Fit 内容模式
【发布时间】:2016-10-19 22:29:26
【问题描述】:

我试图在父视图的中心放置一个UIImageView。图像必须保持其原始纵横比,并且不应超过父级的界限。因此,横向图像应受父级宽度的限制,纵向图像应根据需要占用尽可能多的垂直空间,保持原始比例。

对于 AutoLayout 来说,这听起来很简单,对吧?这是我对UIImageView 的设置:

  • 在父级中垂直居中
  • 在父级中水平居中
  • imageView.width
  • imageView.height

我还将contentMode 设置为Aspect Fit。对于比设备屏幕小的小图像,一切都非常有用,但出于某种原因,我的UIImageView 比其底层UIImage 占用更多空间(注意绿色背景-imageView.backgroundColor = [UIColor greenColor])。

为什么会这样?我不是 AutoLayout 专家,因为我的限制对我来说是合理的。如果我使用较小的图像,例如 200x400,那么 UIImageView 在屏幕上恰好占据 200x400 点,没有额外的绿色区域。

我想添加在这种情况下显然无法正常工作的边框和圆角。

【问题讨论】:

    标签: ios uiimageview autolayout ios-autolayout


    【解决方案1】:

    这是因为您将宽度和高度限制设置为

    • 如果您确定知道纵横比,则可以将其设置为约束并 你不会看到任何绿色背景。
    • 否则就离开你的 约束,并将背景颜色设置为清除颜色。这 这样任何未占用的区域都将是透明的,并且您设置的任何图像 将在至少一个维度上占用最大空间。

    编辑:

    可能不是最好的解决方案,有点老派。您可以添加严格的宽度和高度约束并使用图像的 aspectRatio 手动计算它们:

    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    @IBOutlet weak var widthConstraint: NSLayoutConstraint!
    
    func setImage(image: UIImage) {
        imageView.image = image
        let screenSize = UIScreen.main.bounds.size
    
        let imageAspectRatio = image.size.width / image.size.height
        let screenAspectRatio = screenSize.width / screenSize.height
    
        if imageAspectRatio > screenAspectRatio {
            widthConstraint.constant = min(image.size.width, screenSize.width)
            heightConstraint.constant = widthConstraint.constant / imageAspectRatio
        }
        else {
            heightConstraint.constant = min(image.size.height, screenSize.height)
            widthConstraint.constant = heightConstraint.constant * imageAspectRatio
        }
        view.layoutIfNeeded()
    }
    

    【讨论】:

    • 不幸的是,我事先不知道纵横比,因为我需要在此视图中显示不同的图像:大、小、风景、肖像甚至正方形。截图中的图像具有 3264x2448 分辨率,实际上它被适当地缩小了:它保持了它的比例,它没有被截断或扭曲。但不幸的是,图像视图比图像本身占用更多的物理空间。添加绿色背景仅用于测试目的。透明背景不起作用,因为我需要添加圆角,但这些角将不可见,因为图像视图的边缘与图像不同步。
    • 但我想我可以尝试以编程方式添加相应的纵横比约束......听起来像一个计划:)但实际上我可以在没有 AutoLayout 的情况下以编程方式计算和设置所有内容,所以这个问题的想法是要了解它是否可以在不编写任何 Swift / Objective-C 代码的情况下实现。
    • @fraggjkee:好的,但是如果您的计划失败,请使用更新答案中的我的功能。我已经用大小、纵向和横向图像对其进行了测试,似乎可以按预期工作。
    • 是的,纵横比约束是解决我的问题的关键,感谢@alexburtnik。但不是以编程方式计算宽度/高度,我只计算纵横比并更新相应的约束。
    • 我有一个类似的问题,我将图像视图和其他几个视图放在滚动视图中。我将图像视图限制为主视图的宽度,但发生的情况是自动布局似乎基于完整大小的图像进行计算,而不是适合的图像,因此它在图像上方和下方创建了额外的空间,即使有是将图像与上面的视图和下面的视图齐平的约束。
    【解决方案2】:

    尝试在 Interface Builder 中检查 imageView 的“Clip to BoundsClip to Bounds Image View

    而且你必须有一个明确定义的高度和宽度,而不是“

    【讨论】:

    • 这是救命稻草!我对具有纵横比约束但在内容模式下也具有纵横比填充的图像视图有一个大问题。 imageview 只是不断扩展和覆盖其他内容。甚至不知道如何描述这个问题,但是当我无意中读到这个 ​​0 票的答案时,它确实拯救了我的一天!谢谢克里斯蒂娜!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 2011-12-26
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多