隐藏内部视图时,UIStackView 将内容向左移动

Posted

技术标签:

【中文标题】隐藏内部视图时,UIStackView 将内容向左移动【英文标题】:UIStackView shift content to left when inner views are hidden 【发布时间】:2018-12-14 08:01:23 【问题描述】:

我在水平堆栈视图中有 3 个按钮。如果隐藏了一个或两个按钮,我想将按钮向左移动。它基本上是左移操作。我在情节提要中尝试了几个堆栈视图选项,但不确定我是否走在正确的轨道上。

如何在堆栈视图或其他方式中进行操作?

【问题讨论】:

可能相关? ***.com/questions/40254889/… 【参考方案1】:

在隐藏按钮时更新stackview尾随约束。

@IBOutlet weak var stackViewTrailing: NSLayoutConstraint!

func hideButton(button: UIButton) -> Void 
     button.isHidden = true

     stackViewTrailing.constant += button.frame.width

【讨论】:

虽然这不是实现目标的好方法,但它可能对你有用。但请记住,堆栈视图并不是这样引入的【参考方案2】:

如果您有一个未设置约束的堆栈视图,则堆栈视图的大小就是其内容的大小。假设括号 [] 是您的堆栈视图,X 代表您的按钮,如果您只给堆栈视图一个前导约束、任何类型的垂直约束并将分布设置为“平等填充”,它将表现如下:

---8px---[X X X X]

移除/隐藏一个按钮:

---8px---[X X X]

这听起来像您正在寻找的行为。

另一个注意事项:如果堆栈视图的按钮分布不均等,即使您将其分布设置为“均等填充”,请确保为您的第一个(或更多)按钮提供宽度和高度限制。

【讨论】:

是的,这就是我想要实现的。但是,如果我不把它固定在右边,那么它就不会被平均填充。我想在显示三个按钮时保持相等,并在隐藏按钮时向左移动。 您的意思是按钮在整个设备屏幕的堆栈视图中填充不均?这就是为什么您必须将堆栈视图固定在左侧和右侧?你想要做的是反对堆栈视图的性质。但是,您可以通过在隐藏按钮时在堆栈视图的末尾插入一个空的 UIView 并在再次显示按钮时删除任何空的 UIView 来做一个有点古怪的解决方法。否则,您将不得不在没有堆栈视图的情况下凑合着使用,并让它们每个都使用约束来触摸它们左侧的 UIButton。 @Dan - 这是使用UIStackView的实际方式。【参考方案3】:

非常简单。请按照以下步骤操作。

1) 在将所有 3 张图片设置到其中之后,首先为 StackView 提供正确的 Constrain

2) 然后给堆栈视图一个固定的宽度。并创建StackView Constrain Width Outlet。检查图像。

@IBOutlet var discardWidth: NSLayoutConstraint!

3) 用2 images 计算StackView width。在我的例子中,stackView with 3 images 的宽度是 100px2 images 的宽度是 69px

4) 编码如下。

     if // **Your Condition** 
            img1.isHidden = true
            discardWidth.constant = 69
         else 
            img1.isHidden = false
            discardWidth.constant = 100

简单的权利。它只是向您显示正确的图像而没有拉伸图像。查看下图。

【讨论】:

【参考方案4】:

将 IBOutlet 连接到您的按钮。现在在你的按钮上设置一些条件。当满足这些条件时,您可以将按钮的对齐方式设置为左对齐。以编程方式尝试。

// These are IBOUtlet Collections
@IBOutlet var buttons: [UIButton]!
@IBOutlet var hideButtons: [UIButton]!

override func viewDidLoad() 
  super.viewDidLoad()
  configureButtons()


private func configureButtons() 
  for (index, button) in buttons.enumerated() 
    button.tag = index
    button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
  
  for (index, button) in hideButtons.enumerated() 
    button.tag = index
    button.addTarget(self, action: #selector(hidePressed(_:)), for: .touchUpInside)
    button.setTitle("Show", for: .selected)
  


@objc private func hidePressed(_ sender: UIButton) 
  sender.isSelected = !sender.isSelected

  buttons[sender.tag].isHidden = sender.isSelected

  var totalHiddenCount = 0
  for button in buttons 
    if button.isHidden == true 
      totalHiddenCount += 1
    
  
  for button in buttons 
    if totalHiddenCount >= 2 
      button.contentHorizontalAlignment = .left
     else 
      button.contentHorizontalAlignment = .center
   
  
 

@objc private func buttonPressed(_ sender: UIButton) 

【讨论】:

如果我隐藏两个按钮并只显示一个按钮,它确实有效。如果我隐藏中间按钮,那么第三个按钮就不会留下。 还要检查堆栈视图的对齐方式。 堆栈视图固定在左右两侧,与此有关吗?

以上是关于隐藏内部视图时,UIStackView 将内容向左移动的主要内容,如果未能解决你的问题,请参考以下文章

动态大小嵌套的 UIStackView

UIStackView 图层属性

在 iOS 9 上更改隐藏属性时 UIStackView 不会动画

将 UIStackView 视图动画化到中心

如何在 UIStackView 中保留隐藏视图的约束

即使隐藏了排列的子视图,UIStackView 似乎也会堆叠间距