如何以编程方式修改 UIButton 的约束
How to modify programmatically constraints of UIButton
我在情节提要中写了 2 个具有不同约束的按钮。
在我的代码中,我必须告诉我的第一个按钮采用与第二个按钮相同的约束(高度、宽度、 和位置 ),但我不知道如何在不传递的情况下执行此操作通过 "subview"。我的按钮有 2 个插座。
@IBOutlet weak var likesButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
我的界面是这样构建的:
-
VIEW
a)...View
b)...View
c) ContentView
1)likeButton
2)shareButton
3)...
d)...
我这样试过:
self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.shareButton.removeConstraints(self.shareButton.constraints) // Old Constraints
self.shareButton.addConstraints(self.likeButton.constraints) // New Constraints
self.shareButton.updateConstraintsIfNeeded()
self.shareButton.layoutIfNeeded()
然后出现此错误:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x14cfe7600 H:[UIButton:0x14cfb7bd0(40)]> view:<UIButton: 0x14e30fa60; frame = (494 528; 26 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x14e30f410>>'
提前致谢。
Does the constraint reference something from outside the subtree of the view?
这好像是说...
Does the constraints of likeButton reference something from outside the subtree of the shareButton?
因此,likeButton 约束引用(如 likeButton 本身)完全在 shareButtons 视图层次结构之外。不能这样添加。
您可以改为:
self.view.removeConstraints(self.shareButton.constraints)
self.view.addConstraints(self.likeButton.constraints)
但这不会完成您想要做的任何事情。
约束不仅仅是数字和维度。它还定义了受约束的两个对象。因此,尝试将一个视图约束映射到另一个视图约束是行不通的,因为它不会更改约束中引用的视图。
您可能会想出一种方法来使用各种约束的出口并将约束常量从一个视图中拉出并将它们分配给另一个视图。
如果这是您的情况:
- 您的按钮 和 约束已在 IB 中设置,您希望 更改或替换 约束 一一 代码
然后您可以为每个约束设置一个 IBOutlet 并按名称进行编辑(更改、替换甚至停用它们)。
@IBOutlet weak var likesConstraintLeading: NSLayoutConstraint!
@IBOutlet weak var likesConstraintTop: NSLayoutConstraint!
@IBOutlet weak var likesConstraintWidth: NSLayoutConstraint!
likesConstraintLeading.isActive = false
likesConstraintTop.constant = 20
likesConstraintWidth.multiplier = 3.5
- 您的按钮和约束已在IB中设置,您希望替换 整个 为单个 IBOutlet 命名按钮设置约束
您可以在代码中将新的约束集设置为一个数组,并在删除旧约束后激活它们。
@IBOutlet weak var likesConstraintTop: NSLayoutConstraint!
@IBOutlet weak var likesConstraintLeading: NSLayoutConstraint!
@IBOutlet weak var likesConstraintWidth: NSLayoutConstraint!
var newConstraints = [NSLayoutConstraint]()
newConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor))
newConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 20))
newConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 100))
likesConstraintLeading.isActive = false
likesConstraintTop.isActive = false
likesConstraintWidth.isActive = false
NSLayoutConstraint.activate([newConstraints])
请注意 - 您仍然需要一个一个地取消激活,因为这些约束(宽度除外)已添加到控件的超级视图中,并且其中可能还有更多约束!
- 您在 IB 中设置了按钮,但您希望通过代码维护一组约束。
恕我直言,这是您可以执行的最佳设置,因为您可以仍然通过 IB 添加所有其他约束,并将您的代码限制为您希望更改的内容。
var startingConstraints = [NSLayoutConstraint]()
var endingConstraints = [NSLayoutConstraint]()
override func viewDidLoad() {
startingConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor))
startingConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 20))
startingConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 100))
endingConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30))
endingConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 40))
endingConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 80))
NSLayoutConstraint.activate([startingConstraints])
}
func changeConstraints() {
NSLayoutConstraint.deactivate([newConstraints])
NSLayoutConstraint.activate([newConstraints])
}
我在情节提要中写了 2 个具有不同约束的按钮。 在我的代码中,我必须告诉我的第一个按钮采用与第二个按钮相同的约束(高度、宽度、 和位置 ),但我不知道如何在不传递的情况下执行此操作通过 "subview"。我的按钮有 2 个插座。
@IBOutlet weak var likesButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
我的界面是这样构建的:
-
VIEW
a)...View
b)...View
c) ContentView
1)likeButton
2)shareButton
3)...
d)...
我这样试过:
self.contentView.translatesAutoresizingMaskIntoConstraints = false
self.shareButton.removeConstraints(self.shareButton.constraints) // Old Constraints
self.shareButton.addConstraints(self.likeButton.constraints) // New Constraints
self.shareButton.updateConstraintsIfNeeded()
self.shareButton.layoutIfNeeded()
然后出现此错误:
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal. constraint:<NSLayoutConstraint:0x14cfe7600 H:[UIButton:0x14cfb7bd0(40)]> view:<UIButton: 0x14e30fa60; frame = (494 528; 26 31); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x14e30f410>>'
提前致谢。
Does the constraint reference something from outside the subtree of the view?
这好像是说...
Does the constraints of likeButton reference something from outside the subtree of the shareButton?
因此,likeButton 约束引用(如 likeButton 本身)完全在 shareButtons 视图层次结构之外。不能这样添加。
您可以改为:
self.view.removeConstraints(self.shareButton.constraints)
self.view.addConstraints(self.likeButton.constraints)
但这不会完成您想要做的任何事情。
约束不仅仅是数字和维度。它还定义了受约束的两个对象。因此,尝试将一个视图约束映射到另一个视图约束是行不通的,因为它不会更改约束中引用的视图。
您可能会想出一种方法来使用各种约束的出口并将约束常量从一个视图中拉出并将它们分配给另一个视图。
如果这是您的情况:
- 您的按钮 和 约束已在 IB 中设置,您希望 更改或替换 约束 一一 代码
然后您可以为每个约束设置一个 IBOutlet 并按名称进行编辑(更改、替换甚至停用它们)。
@IBOutlet weak var likesConstraintLeading: NSLayoutConstraint!
@IBOutlet weak var likesConstraintTop: NSLayoutConstraint!
@IBOutlet weak var likesConstraintWidth: NSLayoutConstraint!
likesConstraintLeading.isActive = false
likesConstraintTop.constant = 20
likesConstraintWidth.multiplier = 3.5
- 您的按钮和约束已在IB中设置,您希望替换 整个 为单个 IBOutlet 命名按钮设置约束
您可以在代码中将新的约束集设置为一个数组,并在删除旧约束后激活它们。
@IBOutlet weak var likesConstraintTop: NSLayoutConstraint!
@IBOutlet weak var likesConstraintLeading: NSLayoutConstraint!
@IBOutlet weak var likesConstraintWidth: NSLayoutConstraint!
var newConstraints = [NSLayoutConstraint]()
newConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor))
newConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 20))
newConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 100))
likesConstraintLeading.isActive = false
likesConstraintTop.isActive = false
likesConstraintWidth.isActive = false
NSLayoutConstraint.activate([newConstraints])
请注意 - 您仍然需要一个一个地取消激活,因为这些约束(宽度除外)已添加到控件的超级视图中,并且其中可能还有更多约束!
- 您在 IB 中设置了按钮,但您希望通过代码维护一组约束。
恕我直言,这是您可以执行的最佳设置,因为您可以仍然通过 IB 添加所有其他约束,并将您的代码限制为您希望更改的内容。
var startingConstraints = [NSLayoutConstraint]()
var endingConstraints = [NSLayoutConstraint]()
override func viewDidLoad() {
startingConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor))
startingConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 20))
startingConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 100))
endingConstraints.append(likesButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30))
endingConstraints.append(likesButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 40))
endingConstraints.append(likesButton.widthAnchor.constraint(equalToConstant: 80))
NSLayoutConstraint.activate([startingConstraints])
}
func changeConstraints() {
NSLayoutConstraint.deactivate([newConstraints])
NSLayoutConstraint.activate([newConstraints])
}