NSLayoutConstraint 问题

Posted

技术标签:

【中文标题】NSLayoutConstraint 问题【英文标题】:NSLayoutConstraint problen 【发布时间】:2018-01-26 06:31:48 【问题描述】:
//MARK: NSLayoutConstraints
//trailing
let trailingConstaint = NSLayoutConstraint(item: imageView, attribute: .trailing, relatedBy: .equal, toItem:imageView.superview , attribute: .trailing, multiplier: 1, constant: 0)
trailingConstaint.isActive = true

//leading
let leadingConstraint = NSLayoutConstraint(item: imageView, attribute: .leading, relatedBy: .equal, toItem: imageView.superview, attribute: .leading, multiplier: 1, constant: 0)
leadingConstraint.isActive = true

//top
let topConstraint = NSLayoutConstraint(item: image, attribute: .top, relatedBy: .equal, toItem: imageView.superview, attribute: .top, multiplier: 1, constant: 0)
topConstraint.isActive = true

//bottom
let bottomConstraint = NSLayoutConstraint(item: imageView, attribute: .bottom, relatedBy: .equal, toItem: imageView.superview, attribute: .bottom, multiplier: 1, constant: 0)
bottomConstraint.isActive = true

我想调整图像的大小以使其适合,以便正确缩放图像 screenshot of ViewController

但是我得到了这个错误..

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'NSLayoutConstraint for 大小 746, 496 方向 0 比例 1.000000:每个约束项都必须是 UIView 或 UILayoutGuide 的实例。'

【问题讨论】:

必须定义视图之间的约束,这些视图是同一视图的子视图。 【参考方案1】:
//top
let topConstraint = NSLayoutConstraint(item: image, attribute: .top, relatedBy: .equal, toItem: imageView.superview, attribute: .top, multiplier: 1, constant: 0)
topConstraint.isActive = true

您将此约束设置为 image 而不是 imageView

异常明确指出Constraint items must each be an instance of UIView, or UILayoutGuide.'

所有其他约束都设置在 imageViewimageView.superView 之间,因此从逻辑上讲,上述约束也应该使用同一对。

这将处理异常。

//top
let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: imageView.superview, attribute: .top, multiplier: 1, constant: 0)
topConstraint.isActive = true

但是,图像缩放不能通过约束来实现。您必须适当地设置 contentMode 属性。查看well-explained docs.中的了解图像的缩放方式部分

【讨论】:

是的,我只需要用 imageView 替换图像。这是我这边的一个愚蠢错误。感谢您的帮助。 我实际上是在尝试用从 photoLibrary 中选择的新图像替换占位符的旧约束。 更改内容时不需要更改约束。图片将根据contentMode 和现有约束调整大小。 但是,正如@Paulw11 在他的回答中所建议的那样,我也坚持最好将您的约束放在情节提要中。【参考方案2】:

看起来您在 topConstraint 中引用了 image 而不是 imageView。 如果没有看到更多代码,很难确定,但请尝试更新它并查看它是否有效。

let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: imageView.superview, attribute: .top, multiplier: 1, constant: 0)
topConstraint.isActive = true

【讨论】:

是的,这是我的一个愚蠢错误。感谢您的帮助。【参考方案3】:

在第三个约束中,您使用了image 而不是imageView。您不能对图像设置约束,只能对视图设置约束。看看你是怎么设置imageView的。

您是否有理由不简单地在 Interface Builder 中设置约束?它们非常直截了当。

您可以设置UIImageViewcontentMode 属性来确定图像的缩放方式。 scaleAspectFill 通常是您想要的,尽管如果图像不完全适合视图,这将导致图像被裁剪。 scaleAspectFit 将确保显示整个图像,但如果图像大小与视图大小不匹配,则需要一些填充。 scaleToFill 将在没有填充的情况下填充视图,可能会以扭曲图像为代价。

【讨论】:

我实际上在 imageView 中有一个图像作为带有约束的占位符。但是我从照片库中选择了一个图像并赋予它新的约束来替换以前的约束。谢谢你的帮助。跨度>

以上是关于NSLayoutConstraint 问题的主要内容,如果未能解决你的问题,请参考以下文章

NSLayoutConstraint 的问题

NSLayoutConstraint 激活/停用

旋转设备后 safeAreaLayoutGuide 未更新

如何检查 NSLayoutConstraint 是不是动画

如何创建返回 NSLayoutConstraint 的函数

无法获取 NSLayoutConstraint 的约束