繁体   English   中英

UIStackView 中的重叠视图

[英]Overlapping Views in UIStackView

我有一个水平堆栈视图,我向其中添加了排列的子视图(7 个单元格)。 堆栈中的每个单元格都有一个超出视图边界的圆形标志(负约束)。 运行时,如下所示,每个单元格都位于前一个单元格的徽章之上。 我想更改顺序,以便徽章完全可见。

在此处输入图像描述

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

在此处输入图像描述

任何想法或建议如何做到这一点?

谢谢。

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

@IBOutlet weak var stackView: UIStackView!

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

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


2022年的东西:

甚至更迅捷...

@IBOutlet weak var stackView: UIStackView!

stackView.arrangedSubviews.forEach({ stackView.sendSubviewToBack($0) })

UIStackView 类的文档告诉我们:

子视图数组的顺序定义了子视图的 Z 顺序。 如果视图重叠,则索引较低的子视图出现在索引较高的子视图后面。

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

在此处输入图像描述

这不涵盖一般情况,因为设备可能已在其全局设置中设置了 RTL 语言。 对于一般情况,我想我需要检查接口语义并强制与我的堆栈视图相反的方向。

PS 这是一种 hack,所以任何关于如何以不同方式重新排列子视图的 Z 顺序的想法都将受到欢迎!

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

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

安排子视图的文档

下面是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() }
    }
  }

}

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

我有一个类似的问题,但每个子视图都必须有特定的背景。 就我而言,你的 hack 可能会有所帮助……😉 谢谢!

以编程方式添加子视图时,添加高度和宽度常量约束。 最后调用 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()

我希望防止重叠在一起。 我尝试了sendSubviewToBack方法,但所做的只是将重叠转移到另一边,这并不奇怪。

就我而言,这是由我的子视图上的图像视图设置为scaleToFill的,这意味着某些图像实际上与下一个视图重叠。 我对此的解决方案是,在我的子视图类(进入堆栈视图的视图)中,只需启用掩码到边界

view.maskToBounds = true

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

在我的情况下, UIStackView 在 UITableViewCell 里面,我把头发拉出来为什么单元格重叠。 这是prepareForReuse()的解决方法:

extension UIStackView
{
  func wipeClean() {
    arrangedSubviews.forEach {
      removeArrangedSubview($0)
      // removeArrangedSubview does not removeFromSuperview
      // hence do the explicit
      $0.removeFromSuperview() }
  }
}

大约两天浪费了导致removeArrangedSubview并不意味着removeFromSuperview

L for Logic:视图不参与堆栈布局,但显示在屏幕上。 我会对 Apple 认为这可能有用的地方感兴趣。

对我来说,我写了这段代码:

stackView.translatesAutoresizingMaskIntoConstraints = true

所以我只是删除了那行代码,我对 go 很好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM