列表中的SwiftUI zIndex

时间:2020-04-09 02:51:14

标签: swift swiftui

zIndexForEach内的视图上的List属性似乎不起作用,而如果zIndex内的ForEach中有ScrollView ,确实如此。

不适用于我:

List {
    ForEach { index
       View()
          .zIndex(index == 1 ? 1 : 0)
    }
}

作品:

VStack {
    ScrollView {
        ForEach { index
           View()
              .zIndex(index == 1 ? 1 : 0)
        }
    }
}

有人知道为什么吗?

1 个答案:

答案 0 :(得分:0)

似乎 zIndex 在 SwiftUI(甚至 SwiftUI 2)中的 List 中不起作用。一种解决方法可能是内省 UITableViewCell 并更改它的 zPosition 图层,如下所示;

 var body: some View {
    List {
        Text("First Row")
            .background(Color.green)
            .padding()
            .listRowZIndex(1)
        Text("Second Row")
            .background(Color.red)
            .padding()
            .listRowZIndex(0)
            .offset(x: 0, y: -30)
    }
 }

然后创建 ViewModifier ;

struct ListRowZIndex: ViewModifier {
    
    @State var zIndex : CGFloat = 0.0
        
    func body(content: Content) -> some View {
        content.background(ListRowZindexHelperView(zIndex: zIndex))
    }
}

extension View {
    func listRowZIndex(_ index: CGFloat = 0.0) -> some View {
            self.modifier(ListRowZIndex(zIndex: index))
    }
}

必需的实现;

struct ListRowZindexHelperView: UIViewRepresentable {
    let zIndex : CGFloat
    let proxy = ListRowZindexHelperProxy(cellWrapper: UITableViewCellWrapper(cell: UITableViewCell()))
    
    func makeUIView(context: Context) -> UIView {
        return UIView()
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        proxy.catchUITableViewCell(for: uiView)
        proxy.chnageZIndex(zIndex)
    }
}


class ListRowZindexHelperProxy {

    var uiTableViewCellWrapper: UITableViewCellWrapper
    
    init(cellWrapper: UITableViewCellWrapper) {
        uiTableViewCellWrapper = cellWrapper
    }

    func catchUITableViewCell(for view: UIView) {
        if let cell = view.enclosingUITableViewCell() {
            uiTableViewCellWrapper.uiTableViewCell = cell
        }
    }

    func chnageZIndex(_ zIndex: CGFloat = 0.0) {
        uiTableViewCellWrapper.uiTableViewCell.layer.zPosition = zIndex
    }
}

class UITableViewCellWrapper {
    var uiTableViewCell : UITableViewCell
    
    init(cell: UITableViewCell) {
        uiTableViewCell = cell
    }
}

extension UIView {
    func enclosingUITableViewCell() -> UITableViewCell? {
        var next: UIView? = self
        repeat {
            next = next?.superview
            if let asUITableViewCell = next as? UITableViewCell {
                return asUITableViewCell
            }
        } while next != nil
        return nil
    }
}

结果; Preview

第二行在第一行之后,因为第一行现在有更高的 zIndex

答案灵感from this answer