隐藏视图时,自动布局中的 Swift 约束不会改变

Posted

技术标签:

【中文标题】隐藏视图时,自动布局中的 Swift 约束不会改变【英文标题】:Swift constraint doesnot change in Autolayout while hiding views 【发布时间】:2016-11-17 10:54:13 【问题描述】:

这些是我的代码 //我的 UIViews

@IBOutlet weak var UIVIewFirst: UIView!
@IBOutlet weak var UIViewSecond: UIView!
@IBOutlet weak var UIViewThird: UIView!

@IBOutlet weak var middleViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var ViewThirdHeight: NSLayoutConstraint!

有一个按钮可以显示和隐藏视图;

    @IBAction func infoClicked(sender: s-s-radioButton) 
    if UIViewSecond.hidden 
        sender.selected = false
        UIViewSecond.hidden = false
        self.middleViewHeightConstraint.constant = 134

     else 
        sender.selected = true
        UIViewSecond.hidden = true
        self.middleViewHeightConstraint.constant = 0
        self.ViewThirdHeight.constant = 180
    

每个视图之间的垂直间隙为 10。隐藏视图后,间隙变为 20。但我需要它在第三和第二个视图之间设置 10。即使我将第三个视图高度常数设置为任何数字,它也不会改变它的位置。谁能建议为什么会发生这种情况??

【问题讨论】:

在修改约束结束时使用view.setNeedsLayout() 【参考方案1】:

您需要在First-SecondSecond-Third 视图之间获取vertical spacing 约束的出口连接。此外,如果您只想隐藏/显示Second view,则无需对Third View height constraint 进行任何更改。

比如说我们取vertical spacing between First and Second views的出口,那么:

@IBOutlet weak var UIVIewFirst: UIView!
@IBOutlet weak var UIViewSecond: UIView!

@IBOutlet weak var middleViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var verticalSpacingConstraint: NSLayoutConstraint!

@IBAction func infoClicked(sender: UIButton)

    if UIViewSecond.hidden
    
        sender.selected = false
        UIViewSecond.hidden = false
        self.middleViewHeightConstraint.constant = 134
        self.verticalSpacingConstraint.constant = 10
    
    else
    
        sender.selected = true
        UIViewSecond.hidden = true
        self.middleViewHeightConstraint.constant = 0
        self.verticalSpacingConstraint.constant = 0
    

以下是输出截图:

1.未选择按钮时

2。选择按钮时

【讨论】:

【参考方案2】:

你还没有告诉你的视图用新的约束更新视图,你必须调用这个代码:

self.view.layoutIfNeeded()

【讨论】:

我应该在哪里添加这个??请详细说明..这是否支持自动布局? 就在上面的代码之后,在你改变你的约束之后,你必须调用它,是的,这告诉你的自动布局用新的约束再次布局 它应该可以工作,如果没有,那么你的约束是错误的,或者它只是没有改变任何东西 我在 self.middleViewHeightConstraint.constant = 0 之后添加了它。它不会改变任何东西。 视图中的子视图类型可能很重要。昨晚我艰难地了解到 UISlider,即使是隐藏的,无论如何都有一个内在的宽度。我唯一的解决方案(到目前为止)是“忍受它”。【参考方案3】:
firstView
   | gap = 10
secondView
   | gap = 10
thirdView

删除secondView

    firstView
       | gap = 10
  ---------- height = 0
       | gap = 10
   thirdView

所以差距变成20

尝试在隐藏视图后以编程方式添加约束或减少任何间隙。

【讨论】:

是的,我知道差距是如何变成 20 的。但我已经给出了第三个视图的限制,但它不起作用 尝试在修改约束结束时使用setNeedsLayout()【参考方案4】:

约束忽略 hidden 属性。

如果可能满足您的要求,请将您的视图嵌入UIStackView

见this example。

【讨论】:

【参考方案5】:

尝试更改视图的框架而不是更改约束,在进行任何更改后也要执行 view.layoutIfNeeded。

【讨论】:

如果您使用 AutoLayout,更改视图的框架没有影响。 它对我有用,这就是我建议尝试这个的原因,因为有时我会遇到这种情况,当我尝试更改约束时,除了更改框架之外什么都不做。

以上是关于隐藏视图时,自动布局中的 Swift 约束不会改变的主要内容,如果未能解决你的问题,请参考以下文章

自动布局中的比例距离约束

使用自动布局时无法隐藏或删除 UICollectionViewCell 中的视图

iOS 自动布局约束:忽略隐藏或零尺寸视图?

使用带有自动布局的推送时隐藏按钮时,约束更新导致项目移动

Xcode Interface builder 中的 Nib 视图不应用自动布局约束

我的带有自动布局约束的 Swift 4 UIScrollView 没有滚动