以编程方式修改约束 Swift
Modify constraint programmatically Swift
我的故事板中有以下视图控制器:
默认情况下,它总是有 6 个图像视图,它们的宽度和高度相等。每个图像视图都被限制在超级视图中:"equal heights" 和 1/2 的乘数。
但是,在我将图像加载到内部之前,我阅读了一个 属性,它为我提供了图像所需的高度(宽度永远不会被修改)。
所以我的界面(在运行时)看起来像这样:
我想我需要修改乘数常数,但它是只读的。
我看到帖子说我们可以更新约束的 constant 属性 但它很重要,我需要它在每个设备上工作。
现在你会推荐什么?我应该删除约束并添加一个新约束吗?如果我不删除它并尝试应用新的高度限制,它会自动为我删除吗?
我是否必须使用 pods 之类的 snapkit 来完成这项工作?
感谢您的帮助。
编辑
这是我试过但没有成功的代码:
for (index, (drawing, ratio)) in drawingElements.enumerate() {
drawingViews[index].image = UIImage(named: drawing)
// update height constraint if ratio is different than defaut ratio of 1/2
if ratio != 0.5 {
heightConstraints[index].active = false
let newHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.Height, multiplier: ratio, constant: 0)
drawingViews[index].addConstraint(newHeightConstraint)
self.view.layoutIfNeeded()
}
}
我做错了吗?不过我不确定新的高度限制
约束常量与被约束元素的内容有关。
这就是为什么你得到这样的屏幕。最简单的方法 - 创建颜色清晰的图像并将其设置为默认值。下载完成后,只需为您的 imageView 设置新图像
或者您可以为您的高度限制设置 IBOutlet - 并根据不同情况更改它的值
即
if(download.completed)
ibHeightOutlet.constant = imageView.frame.size.height;
else
ibHeightOutlet.constant = initialImageViewHeght.frame.size.height;
由于我不知道的原因(可能是 Apple 的某种实现细节),您无法更改乘数。但是,您可以删除一个约束并创建一个新约束。你必须删除旧的约束,因为它不会自动删除,你会遇到冲突。或者,您可以创建优先级较低的第一个约束(使用 0.5
乘数)。这样你就可以保留它(自动布局会忽略它),但我不认为这是一种方法,因为你为什么需要那个不必要的约束?只需删除它。
至于第三方布局引擎和库——很遗憾,我不能在这里给你任何建议。
这就是我实现这一目标的方式:
以编程方式创建约束(我的高度):
// Drawing height property
var drawingHeightConstraint: NSLayoutConstraint?
停用旧约束并根据需要设置新约束
注意:heightContraints 是 NSLayoutConstraint 的数组,其中包含我的 outlets
for (index, (drawing, ratio)) in drawingElements.enumerate() {
drawingViews[index].image = UIImage(named: drawing)
// update height constraint if ratio is different than defaut ratio of 1/2
if ratio != 0.5 {
heightConstraints[index].active = false
drawingHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: .Height, relatedBy: .Equal, toItem: drawingView, attribute: .Height, multiplier: CGFloat(ratio), constant: 0)
drawingHeightConstraint!.active = true
}
}
- 之后立即调用 layoutIfNeeded()(注意:不确定何时调用它)
我的故事板中有以下视图控制器:
默认情况下,它总是有 6 个图像视图,它们的宽度和高度相等。每个图像视图都被限制在超级视图中:"equal heights" 和 1/2 的乘数。
但是,在我将图像加载到内部之前,我阅读了一个 属性,它为我提供了图像所需的高度(宽度永远不会被修改)。
所以我的界面(在运行时)看起来像这样:
我想我需要修改乘数常数,但它是只读的。
我看到帖子说我们可以更新约束的 constant 属性 但它很重要,我需要它在每个设备上工作。
现在你会推荐什么?我应该删除约束并添加一个新约束吗?如果我不删除它并尝试应用新的高度限制,它会自动为我删除吗?
我是否必须使用 pods 之类的 snapkit 来完成这项工作?
感谢您的帮助。
编辑
这是我试过但没有成功的代码:
for (index, (drawing, ratio)) in drawingElements.enumerate() {
drawingViews[index].image = UIImage(named: drawing)
// update height constraint if ratio is different than defaut ratio of 1/2
if ratio != 0.5 {
heightConstraints[index].active = false
let newHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.Height, multiplier: ratio, constant: 0)
drawingViews[index].addConstraint(newHeightConstraint)
self.view.layoutIfNeeded()
}
}
我做错了吗?不过我不确定新的高度限制
约束常量与被约束元素的内容有关。 这就是为什么你得到这样的屏幕。最简单的方法 - 创建颜色清晰的图像并将其设置为默认值。下载完成后,只需为您的 imageView 设置新图像
或者您可以为您的高度限制设置 IBOutlet - 并根据不同情况更改它的值 即
if(download.completed)
ibHeightOutlet.constant = imageView.frame.size.height;
else
ibHeightOutlet.constant = initialImageViewHeght.frame.size.height;
由于我不知道的原因(可能是 Apple 的某种实现细节),您无法更改乘数。但是,您可以删除一个约束并创建一个新约束。你必须删除旧的约束,因为它不会自动删除,你会遇到冲突。或者,您可以创建优先级较低的第一个约束(使用 0.5
乘数)。这样你就可以保留它(自动布局会忽略它),但我不认为这是一种方法,因为你为什么需要那个不必要的约束?只需删除它。
至于第三方布局引擎和库——很遗憾,我不能在这里给你任何建议。
这就是我实现这一目标的方式:
以编程方式创建约束(我的高度):
// Drawing height property var drawingHeightConstraint: NSLayoutConstraint?
停用旧约束并根据需要设置新约束
注意:heightContraints 是 NSLayoutConstraint 的数组,其中包含我的 outlets
for (index, (drawing, ratio)) in drawingElements.enumerate() {
drawingViews[index].image = UIImage(named: drawing)
// update height constraint if ratio is different than defaut ratio of 1/2
if ratio != 0.5 {
heightConstraints[index].active = false
drawingHeightConstraint = NSLayoutConstraint(item: drawingViews[index], attribute: .Height, relatedBy: .Equal, toItem: drawingView, attribute: .Height, multiplier: CGFloat(ratio), constant: 0)
drawingHeightConstraint!.active = true
}
}
- 之后立即调用 layoutIfNeeded()(注意:不确定何时调用它)