更改 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 数组,每个按钮一次。 (您也可以有单独的变量 firstButtonSizeConstraintssecondButtonSizeConstraints 等,但通过将其设为数组,您可以循环遍历它。)

在您的 setupConstraints 函数中,将这些约束放入局部变量中,将它们添加到您的 ButtonSizeConstraints 数组中,并在您发布的代码之外激活它们。

然后,当您将新图像加载到一个或多个按钮时,获取该按钮的 ButtonSizeConstraints,更新该约束的常量值,并调用父视图的 layoutIfNeeded() 方法。