List 内的 SwiftUI zIndex

Posted

技术标签:

【中文标题】List 内的 SwiftUI zIndex【英文标题】:SwiftUI zIndex inside List 【发布时间】:2020-04-09 02:51:14 【问题描述】:

ForEachList 内的视图上的 zIndex 属性似乎不起作用,而如果您在 ScrollView 内的 ForEach 内有 zIndex,它确实有效。

不适合我:

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

作品:

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

有人知道为什么吗?

【问题讨论】:

您使用的View 类型是什么? 另外,Does not work 是什么意思?它不编译吗?碰撞?还是只是没有预期的行为? @Sam 对不起,要清楚 zIndex 没有生效,我强制到顶部的“行”zIndex 实际上并没有到顶部。 View 是我创建的一些自定义视图 我的猜测是 SwiftUI 中的一个错误——也许尝试在任何地方粘贴Groups 看看它是否有效果? Groups 运气不好 :( 【参考方案1】:

似乎 zIndex 在 SwiftUI 中的 List 中不起作用(甚至是 SwiftUI 2)。一种解决方法可能是自省 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

【讨论】:

以上是关于List 内的 SwiftUI zIndex的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:NavigationLink 内的水平 ScrollView 会中断导航

多行文本在 SwiftUI 列表内的 NavigationLink 中不起作用

如何防止 TextField 在 SwiftUI 列表中消失?

SwiftUI:TextField 内的填充

SwiftUI:数组内的修饰符

选择器内的 SwiftUI 无限循环