首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于自动布局,我如何使UIImageView的大小动态取决于图像?

对于自动布局,我如何使UIImageView的大小动态取决于图像?
EN

Stack Overflow用户
提问于 2014-11-09 21:38:29
回答 8查看 74.3K关注 0票数 70

我希望我的UIImageView增长或缩小,取决于它所显示的实际图像的大小。但我希望它保持垂直中心和10分,从前沿的超级视图。

但是,如果设置这两个约束,它会抱怨我没有设置足够的约束来满足自动布局。在我看来,它似乎完美地描述了我想要的东西。我遗漏了什么?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2014-11-10 00:22:05

图像视图的内在大小已经取决于图像的大小。你的假设(和约束是正确的)。

但是,如果您已经在接口构建器中设置了图像视图,并且没有为其提供图像,那么布局系统(接口构建器)将不知道在编译时图像视图应该有多大。您的布局是模棱两可的,因为您的图像视图可能有许多大小。这就是抛出错误的原因。

设置图像视图的图像属性后,图像视图的内在大小由图像大小定义。如果您在运行时设置视图,那么您可以按照Anna提到的那样做,并在图像视图的属性检查器中为接口生成器提供“占位符”内在大小。这告诉界面生成器,“现在使用这个大小,稍后我会给您一个真正的大小”。占位符约束在运行时被忽略。

您的另一个选择是直接将图像分配给接口生成器中的图像视图(但我假设您的图像是动态的,所以这对您不起作用)。

票数 79
EN

Stack Overflow用户

发布于 2017-03-07 17:19:45

这是一个基本的问题:UIImageView与自动布局交互的唯一方式是通过它的intrinsicContentSize属性。该属性提供图像本身的内在大小,仅此而已。这产生了三种情况,有不同的解决方案。

案例1:具有图像大小的视图

在第一种情况下,如果将UIImageView放置在外部自动布局约束只影响其位置的上下文中,则视图的intrinsicContentSize将声明它希望成为其图像的大小,而自动布局将自动调整视图的大小以等于其图像的大小。这有时正是你想要的,然后生活是美好的!

例2:全约束视图大小,保持图像的纵横比

其他时候,你的情况就不一样了。您知道您希望图像视图的大小,但也希望它保持显示图像的高宽比。在这种情况下,您可以使用自动布局来限制图像的大小,同时在图像视图上将旧的contentMode属性设置为.scaleAspectFit。该属性将导致图像视图重新显示显示的图像,并根据需要添加填充。如果这是你想要的,生活就是美好的!

案例3:部分受限的视图大小,适应图像的纵横比

但通常情况下,你会遇到棘手的第三种情况。您希望使用“自动布局”来部分确定视图的大小,同时允许图像的高宽比确定另一部分。例如,您可能希望使用“自动布局”约束来确定大小的一个维度(如垂直时间线滚动中的宽度),同时依赖该视图告诉“自动布局”它希望一个与图像的纵横比匹配的高度(因此可滚动项不会太短或太高)。

您不能配置一个普通的图像视图来实现这一点,因为图像视图只通信其intrinsicContentSize。因此,如果您将图像视图放置在自动布局约束一维的上下文中(例如,将其限制在较短的宽度),则图像视图不会告诉Auto Layout它希望将其高度串联起来。它继续报告它的内在内容大小,与图像本身未经修改的高度。

为了配置图像视图以告诉Auto布局它想要接受它包含的图像的纵横比,您需要为此添加一个新的约束。此外,每当图像本身被更新时,您将需要更新该约束。您可以构建一个执行此操作的UIImageView子类,因此行为是自动的。下面是一个例子:

代码语言:javascript
运行
复制
public class ScaleAspectFitImageView : UIImageView {
  /// constraint to maintain same aspect ratio as the image
  private var aspectRatioConstraint:NSLayoutConstraint? = nil

  required public init?(coder aDecoder: NSCoder) {
    super.init(coder:aDecoder)
    self.setup()
  }

  public override init(frame:CGRect) {
    super.init(frame:frame)
    self.setup()
  }

  public override init(image: UIImage!) {
    super.init(image:image)
    self.setup()
  }

  public override init(image: UIImage!, highlightedImage: UIImage?) {
    super.init(image:image,highlightedImage:highlightedImage)
    self.setup()
  }

  override public var image: UIImage? {
    didSet {
      self.updateAspectRatioConstraint()
    }
  }

  private func setup() {
    self.contentMode = .scaleAspectFit
    self.updateAspectRatioConstraint()
  }

  /// Removes any pre-existing aspect ratio constraint, and adds a new one based on the current image
  private func updateAspectRatioConstraint() {
    // remove any existing aspect ratio constraint
    if let c = self.aspectRatioConstraint {
      self.removeConstraint(c)
    }
    self.aspectRatioConstraint = nil

    if let imageSize = image?.size, imageSize.height != 0
    {
      let aspectRatio = imageSize.width / imageSize.height
      let c = NSLayoutConstraint(item: self, attribute: .width,
                                 relatedBy: .equal,
                                 toItem: self, attribute: .height,
                                 multiplier: aspectRatio, constant: 0)
      // a priority above fitting size level and below low
      c.priority = (UILayoutPriorityDefaultLow + UILayoutPriorityFittingSizeLevel) / 2.0
      self.addConstraint(c)
      self.aspectRatioConstraint = c
    }
  }
}

如需更多评论,请访问这个要旨

票数 64
EN

Stack Overflow用户

发布于 2018-01-27 13:47:38

对于@algal案例3,我所要做的就是

代码语言:javascript
运行
复制
class ScaledHeightImageView: UIImageView {

    override var intrinsicContentSize: CGSize {

        if let myImage = self.image {
            let myImageWidth = myImage.size.width
            let myImageHeight = myImage.size.height
            let myViewWidth = self.frame.size.width

            let ratio = myViewWidth/myImageWidth
            let scaledHeight = myImageHeight * ratio

            return CGSize(width: myViewWidth, height: scaledHeight)
        }
        return CGSize(width: -1.0, height: -1.0)
    }
}

这将缩放intrinsicContentSize的高度组件。(-1.0,-1.0)在没有图像时返回,因为这是超类中的默认行为。

此外,我不需要为包含图像视图的单元格的表设置UITableViewAutomaticDimension,而且单元格仍然自动大小。图像视图的内容模式是Aspect Fit

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26833627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档