更改 UIButton 的图像后如何更新约束
How do I update constraints after changing UIButton's image
我的项目中有一个迷你游戏,你必须猜测一个国家的国旗,我不使用 Interface Builder,所有 UI 都是用代码编写的。当用户点击其中一个标志时,我加载一组新的国家来猜测,将它们的标志设置为按钮,并且由于标志的大小与以前的不同,我需要调整 UIButton 约束,所以我调用我的函数 setupConstraints()看起来像这样:
func setupConstraints() {
NSLayoutConstraint.activate([
countryNameLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
countryNameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
countryNameLabel.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
firstCountryButton.topAnchor.constraint(equalTo: countryNameLabel.bottomAnchor, constant: 35),
firstCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
firstCountryButton.heightAnchor.constraint(equalToConstant: 120),
firstCountryButton.widthAnchor.constraint(equalTo: firstCountryButton.heightAnchor, multiplier: flagImages[0].getAspectRatio()),
secondCountryButton.topAnchor.constraint(equalTo: firstCountryButton.bottomAnchor, constant: 25),
secondCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
secondCountryButton.heightAnchor.constraint(equalToConstant: 120),
secondCountryButton.widthAnchor.constraint(equalTo: secondCountryButton.heightAnchor, multiplier: flagImages[1].getAspectRatio()),
thirdCountryButton.topAnchor.constraint(equalTo: secondCountryButton.bottomAnchor, constant: 25),
thirdCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
thirdCountryButton.heightAnchor.constraint(equalToConstant: 120),
thirdCountryButton.widthAnchor.constraint(equalTo: thirdCountryButton.heightAnchor, multiplier: flagImages[2].getAspectRatio()),
])
}
这个函数在我最初设置我的视图控制器时工作正常,但是当我调用它来更新约束时,我在日志中得到以下内容:
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x280d92940 UIButton:0x102315180.height == 120 (active)>",
"<NSLayoutConstraint:0x280d92990 UIButton:0x102315180.width == 1.5*UIButton:0x102315180.height (active)>",
"<NSLayoutConstraint:0x280db2b70 UIButton:0x102315180.width == 2*UIButton:0x102315180.height (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x280db2b70 UIButton:0x102315180.width == 2*UIButton:0x102315180.height (active)>
我看到它试图设置两次宽度,但我不知道为什么。我什至不确定我每次调用此函数来设置约束的方法是否正确。
这是一种处理方法:
创建一个结构 ButtonSizeConstraints:
struct ButtonSizeConstraints {
let widthConStraint: NSLayoutConstraint
let heightConstraint: NSLayoutConstraint
}
为您的视图提供一个 ButtonSizeConstraints
数组,每个按钮一次。 (您也可以有单独的变量 firstButtonSizeConstraints
、secondButtonSizeConstraints
等,但通过将其设为数组,您可以循环遍历它。)
在您的 setupConstraints
函数中,将这些约束放入局部变量中,将它们添加到您的 ButtonSizeConstraints
数组中,并在您发布的代码之外激活它们。
然后,当您将新图像加载到一个或多个按钮时,获取该按钮的 ButtonSizeConstraints
,更新该约束的常量值,并调用父视图的 layoutIfNeeded()
方法。
我的项目中有一个迷你游戏,你必须猜测一个国家的国旗,我不使用 Interface Builder,所有 UI 都是用代码编写的。当用户点击其中一个标志时,我加载一组新的国家来猜测,将它们的标志设置为按钮,并且由于标志的大小与以前的不同,我需要调整 UIButton 约束,所以我调用我的函数 setupConstraints()看起来像这样:
func setupConstraints() {
NSLayoutConstraint.activate([
countryNameLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
countryNameLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
countryNameLabel.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -20),
countryNameLabel.heightAnchor.constraint(equalToConstant: 30),
firstCountryButton.topAnchor.constraint(equalTo: countryNameLabel.bottomAnchor, constant: 35),
firstCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
firstCountryButton.heightAnchor.constraint(equalToConstant: 120),
firstCountryButton.widthAnchor.constraint(equalTo: firstCountryButton.heightAnchor, multiplier: flagImages[0].getAspectRatio()),
secondCountryButton.topAnchor.constraint(equalTo: firstCountryButton.bottomAnchor, constant: 25),
secondCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
secondCountryButton.heightAnchor.constraint(equalToConstant: 120),
secondCountryButton.widthAnchor.constraint(equalTo: secondCountryButton.heightAnchor, multiplier: flagImages[1].getAspectRatio()),
thirdCountryButton.topAnchor.constraint(equalTo: secondCountryButton.bottomAnchor, constant: 25),
thirdCountryButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
thirdCountryButton.heightAnchor.constraint(equalToConstant: 120),
thirdCountryButton.widthAnchor.constraint(equalTo: thirdCountryButton.heightAnchor, multiplier: flagImages[2].getAspectRatio()),
])
}
这个函数在我最初设置我的视图控制器时工作正常,但是当我调用它来更新约束时,我在日志中得到以下内容:
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSLayoutConstraint:0x280d92940 UIButton:0x102315180.height == 120 (active)>",
"<NSLayoutConstraint:0x280d92990 UIButton:0x102315180.width == 1.5*UIButton:0x102315180.height (active)>",
"<NSLayoutConstraint:0x280db2b70 UIButton:0x102315180.width == 2*UIButton:0x102315180.height (active)>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x280db2b70 UIButton:0x102315180.width == 2*UIButton:0x102315180.height (active)>
我看到它试图设置两次宽度,但我不知道为什么。我什至不确定我每次调用此函数来设置约束的方法是否正确。
这是一种处理方法:
创建一个结构 ButtonSizeConstraints:
struct ButtonSizeConstraints {
let widthConStraint: NSLayoutConstraint
let heightConstraint: NSLayoutConstraint
}
为您的视图提供一个 ButtonSizeConstraints
数组,每个按钮一次。 (您也可以有单独的变量 firstButtonSizeConstraints
、secondButtonSizeConstraints
等,但通过将其设为数组,您可以循环遍历它。)
在您的 setupConstraints
函数中,将这些约束放入局部变量中,将它们添加到您的 ButtonSizeConstraints
数组中,并在您发布的代码之外激活它们。
然后,当您将新图像加载到一个或多个按钮时,获取该按钮的 ButtonSizeConstraints
,更新该约束的常量值,并调用父视图的 layoutIfNeeded()
方法。