美文网首页
SwiftUI-自定义容器

SwiftUI-自定义容器

作者: rayChow | 来源:发表于2021-07-17 13:42 被阅读0次

    SwiftUI也是可以自定义容器的,我们将创建一个名为 GridStack 的新容器,它可以让我们在网格内创建任意数量的视图。

    //<Content:View>意味着内容必须是符合View协议的控件,而GridView本身也必须符合View协议
    struct GridStack <Content: View>: View {
        let rows: Int, columns: Int
        //定义了一个闭包,返回需要展示的内容
        let content: (Int, Int) -> Content 
    
        var body: some View {
            VStack { 
                ForEach(0..<rows, id: \.self) { row in
                    HStack {
                        ForEach(0..<columns, id: \.self) {column in
                            self.content(row, column)
                        }
                    }
                }
            }
        }
    }
    

    当循环遍历范围时,只有当我们确定范围内的值不会随时间变化时,SwiftUI 才能直接使用范围。这里我们使用ForEach 0..<rows和0..<columns,这两个值都可以随时间变化——例如,我们可能会添加更多行或列。在这种情况下,我们需要添加第二个参数ForEach,id: .self以告诉SwiftUI它如何能够识别循环中的每个视图。
    此时,我们的自定义容器就可以使用了:

    struct ContentView: View {
        var body: some View {
            GridStack(rows: 4, columns: 4) { row, col in
                  HStack {
                      Image(systemName: "\(row * 4 + col).circle")
                      Text("R\(row) C\(col)")
                }
            }
        }
    }
    

    为了更灵活的使用自定义容器,我们可以使用@ViewBuilder-视图构建器,它允许我们发送多个视图并让它为我们形成一个隐式堆栈。
    我们为GridStack创建一个自定义初始化器,以便我们可以将content闭包标记为使用 SwiftUI 的视图构建器系统:

     init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int, Int) -> Content) {
         self.rows = rows
         self.columns = columns
         self.content = content
     }
    
    有了它,SwiftUI 现在将自动在我们的单元格闭包中创建一个 隐式水平堆栈:
    GridStack(rows: 4, columns: 4) { row, col in
        Image(systemName: "\(row * 4 + col).circle")
        Text("R\(row) C\(col)")
    }
    

    相关文章

      网友评论

          本文标题:SwiftUI-自定义容器

          本文链接:https://www.haomeiwen.com/subject/nrcwpltx.html