UIStackView

时间:2016-01-16 12:17:35

标签: ios uistackview

我有一个水平堆栈视图,我添加了子视图(7个单元格)。 堆栈中的每个单元格都具有超出视图边界的圆形徽章(负面约束)。 运行时,如下所示,每个单元格位于上一个单元格徽章的顶部。我想更改订单,以便徽章完全可见。

enter image description here

尝试使用Z索引但是没有帮助,因为在以下视图层次结构中您可以看到这些图层在某种程度上不是平坦的:

enter image description here

有任何想法或建议怎么做?

感谢。

7 个答案:

答案 0 :(得分:11)

documentation for the UIStackView class告诉我们:

  

子视图数组的顺序定义了子视图的Z顺序。如果视图重叠,则具有较低索引的子视图将显示在具有较高索引的子视图后面。

这正是我在问题中所经历的。为了解决我的具体情况,我做了将视图的语义更改为RTL的技巧,如下所示:

enter image description here

这不包括通用案例,因为设备可能已在其全局设置中设置了RTL语言。对于通用情况,我想我需要检查界面语义并强制反向我的堆栈视图。

<强> P.S。这是一种破解,所以任何有关如何以不同方式重新排序子视图Z顺序的想法都将受到欢迎!

答案 1 :(得分:7)

此Swift解决方案使用UIView方法sendSubviewToBack(_:)docs here)反转堆栈视图子视图顺序:

@IBOutlet weak var stackView: UIStackView!

for view in stackView.arrangedSubviews {
    stackView.sendSubviewToBack(view)
}

当我们通过堆栈视图的排列视图(从下到上)前进时,后面的(即更高的)视图被推到底部,从而颠倒了顺序: - )

答案 2 :(得分:3)

从iOS 9.0开始,可以独立设置堆栈视图子视图的z顺序和排列。使用新的ExpressibleByFloatLiteral属性指定堆栈视图轴上的子视图排列。并使用arrangedSubviews属性根据数组中的索引指定子视图z-order。

堆栈视图确保其subviews属性始终是其arrangedSubviews属性的子集。

https://codepen.io/anon/pen/rmmJvy

答案 3 :(得分:1)

另一个想法可能是将子视图(7个单元格)的背景颜色设置为默认值(完全透明)。并且只将堆栈视图本身的背景设置为白色

我有类似的问题,但每个子视图都必须具有特定的背景。在我的情况下,你的黑客可能会有所帮助......谢谢你!

答案 4 :(得分:1)

以下是UIStackView上的简单扩展,用于撤消UIStackView子视图的z-index,并可选择要求布局:

extension UIStackView {

  func reverseSubviewsZIndex(setNeedsLayout: Bool = true) {
    let stackedViews = self.arrangedSubviews

    stackedViews.forEach {
      self.removeArrangedSubview($0)
      $0.removeFromSuperview()
    }

    stackedViews.reversed().forEach(addSubview(_:))
    stackedViews.forEach(addArrangedSubview(_:))

    if setNeedsLayout {
      stackedViews.forEach { $0.setNeedsLayout() }
    }
  }

}

答案 5 :(得分:1)

我一直在努力防止重叠在一起。 我尝试了sendSubviewToBack方法,但所做的只是毫不奇怪地将重叠部分移到了另一侧。

在我的情况下,这是由我的子视图上的图像视图设置为scaleToFill引起的,这意味着某些图像实际上与下一个视图重叠。我的解决方案是在我的子视图类(进入堆栈视图的视图)中,简单地启用蒙版边界

view.maskToBounds = true

这意味着它只会裁剪掉挂在外面的任何东西。

答案 6 :(得分:0)

以编程方式添加子视图时,添加高度和宽度常量约束。最后调用StackView的setNeedsLayout。它将计算并尝试调整间距的视图

经过各种尝试,我可以将其水平放置

 stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
 stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
 stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
 stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true

 stackView.distribution = .equalSpacing
 stackView.spacing = 5
 stackView.axis = .horizontal
 stackView.alignment = .fill


 for i in 0 ..< images.count {
 let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
 // set button image
 photoView.translatesAutoresizingMaskIntoConstraints = false
 photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
 photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true

 stackView.addArrangedSubview(photoView)
 }
 stackView.setNeedsLayout()

 }