以编程方式添加约束会破坏自动布局约束

Posted

技术标签:

【中文标题】以编程方式添加约束会破坏自动布局约束【英文标题】:Programmatically adding constraints breaks auto layout constraints 【发布时间】:2016-12-05 09:15:24 【问题描述】:

编辑 1

您好,这是我第一次使用代码添加约束。我通常只使用界面生成器。在我认为混合视觉添加的约束会干扰编码约束之前,我正在尝试添加一个垂直 UISlider。我现在已经更新了我的代码,因此这个问题只在这个特定的视图容器中使用代码来创建约束。

我所做的是在另一个视图的正下方创建了一个视图。我在里面创建了 3 个与上面视图中文本字段的宽度相匹配的小视图,然后将它们隔开,就像文本字段的隔开方式一样。

仅出于测试目的,我为这 3 个小视图设置了一种颜色,以查看它是否有效,并且确实有效。

当我真正完成应用程序时,那些红色、绿色和蓝色的视图将清晰可见。我想要它们的唯一原因是,当我创建滑块时,我可以将它们中的每一个约束到视图的中心......这就是文本字段上方的标签受到约束的方式。

这里是这个的代码 哪个有效

    // Mark: Hidden View

    let leftHiddenView = UIView()
    let centerHiddenView = UIView()
    let rightHiddenView = UIView()

    let hiddenViews = [leftHiddenView, centerHiddenView, rightHiddenView]

    for views in hiddenViews 

        views.translatesAutoresizingMaskIntoConstraints = false
        sliderContainer.addSubview(views)
        views.backgroundColor = .white

        let widthConstraint = views.widthAnchor.constraint(equalToConstant: 35)
        let heightConstraint = views.heightAnchor.constraint(equalToConstant: 5)

        NSLayoutConstraint.activate([widthConstraint, heightConstraint])
    

    let centerViewHorizontalConstraint = centerHiddenView.centerXAnchor.constraint(equalTo: sliderContainer.centerXAnchor)
    let centerViewTopConstraint = centerHiddenView.topAnchor.constraint(equalTo: sliderContainer.topAnchor, constant: 50)

    NSLayoutConstraint.activate([centerViewHorizontalConstraint, centerViewTopConstraint])

    let leftViewVerticalCenterConstraint = leftHiddenView.centerYAnchor.constraint(equalTo: centerHiddenView.centerYAnchor, constant: 0)
    let leftViewTrailingConstraint = leftHiddenView.trailingAnchor.constraint(equalTo: centerHiddenView.leadingAnchor, constant: -60)


    NSLayoutConstraint.activate([leftViewVerticalCenterConstraint, leftViewTrailingConstraint])

    let rightViewVerticalCenterConstraint = rightHiddenView.centerYAnchor.constraint(equalTo: centerHiddenView.centerYAnchor, constant: 0)
    let rightViewTrailingConstraint = rightHiddenView.leadingAnchor.constraint(equalTo: centerHiddenView.trailingAnchor, constant: 60)

    NSLayoutConstraint.activate([rightViewVerticalCenterConstraint, rightViewTrailingConstraint])

现在,我开始添加 UISlider 作为垂直。而之前发生的完全相同的事情现在也发生了。

如你所见,一切都崩溃了。

这是目前为止的代码

    // Mark: Slider View

    let leftSlider = UISlider()
    let centerSlider = UISlider()
    let rightSlider = UISlider()

    let colorSliders = [leftSlider, centerSlider, rightSlider]

    for slider in colorSliders 

        slider.translatesAutoresizingMaskIntoConstraints = false
        sliderContainer.addSubview(slider)

        let w = sliderContainer.bounds.width
        slider.bounds.size.width = w
        slider.center = CGPoint(x: w/2, y: w/2)
        slider.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_2))

        slider.value = 0
        slider.minimumValue = 0
        slider.maximumValue = 255

        let sliderTopConstraint = slider.topAnchor.constraint(equalTo: centerHiddenView.bottomAnchor, constant: 5)
        let sliderBottomConstraint = slider.bottomAnchor.constraint(equalTo: sliderContainer.bottomAnchor, constant: 5)

        NSLayoutConstraint.activate([sliderTopConstraint, sliderBottomConstraint])
        slider.backgroundColor = .purple

    

    let centerSliderHorizontalConstraints = centerSlider.centerXAnchor.constraint(equalTo: sliderContainer.centerXAnchor)
    NSLayoutConstraint.activate([centerSliderHorizontalConstraints])

【问题讨论】:

我的意思是它不仅破坏了自己的容器,还破坏了一个单独的容器 【参考方案1】:

永远不要将设计时间约束与添加运行时约束混为一谈。在设计时添加所有约束或仅在运行时添加所有约束。否则你将陷入混乱。将此作为一种良好做法。

如果您需要更改框架,只需更改约束的常量属性并在设计时添加所有必需的约束。

您需要添加运行时约束的情况非常少见。 (我这么说是因为我总是只以这种方式设计。这对我很有帮助。)以这样的方式设计你的屏幕,即使你需要为动态 UI 更改添加 2 个控件,然后保留 2 个控件并显示用那个控件隐藏。如果您的控件需要某种动画,则无需更改设计时间限制。

我知道这并不能直接回答您的问题,但希望您了解如何使用约束。

从您的屏幕截图中,我无法确切了解您的 UI 是什么样的。你能稍微了解一下你的 UI 是什么样子的吗?这样我就可以提出一些关于如何给予约束的想法......

【讨论】:

嗨,是的,所以 UI 基本上位于顶行 3 个 UILabel:R、G、B。每个 UILabel 的正下方是一个 UITextField。我想要完成的是在每个 UITextField 正下方添加一个垂直 UISlider。每一列,即 R,它下面的文本字段,以及添加的滑块将彼此水平居中,G 和 B 也是如此 你试过保持 translatesAutoresizingMaskIntoConstraints= true 吗? 是的,让事情变得更糟 哦...那你可以试试***.com/questions/13706255/…。似乎 CGAffineTransform 是您问题的主要罪魁祸首。因此,您面临 AutoLayout 的问题。因此,如果有帮助,请尝试使用锚点... ***.com/questions/12943107/…【参考方案2】:

好吧,事实证明,这个问题实际上从一开始就很容易解决。我只是因为被垂直 UISlider 吓倒而忽略了它。因为当我在上面添加容器并运行应用程序时,我没有给上面的容器一个固定的高度,所以容器同样填满了空间,里面的内容也相应地混乱了。我只是将带有标签和文本字段的顶部容器设置为 61 的固定高度,现在它离完成更近了。对不起

【讨论】:

以上是关于以编程方式添加约束会破坏自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

模糊自动布局约束(以编程方式添加)

以编程方式向导航控制器添加自动布局约束

ObjC,在以编程方式添加/删除后恢复为界面构建器自动布局约束?

以编程方式使用自动布局添加许多按钮以查看 X、Y、填充约束

以编程方式应用自动布局约束时无法同时满足约束

以编程方式为不同大小类创建具有不同常量的自动布局约束