繁体   English   中英

如何实现动态 SwiftUI 视图层次结构?

[英]How to Implement Dynamic SwiftUI View Hierarchy?

我正在尝试使用 SwiftUI 实现 markdown 渲染器。 Markdown 文档包含各种块,其中一个块可能嵌入到另一个块中,例如块引用:

报价 1 级

报价级别 2

报价等级 3

...

整个文档 forms 是一个任意深度的树状结构,需要渲染器采用递归的方式。 我采用了以下代码结构:

@ViewBuilder
func renderBlock(block: Block) -> some View {
    switch block {
    // other types of elements
    case let block as BlockQuote:
        HStack {
            GrayRectangle()
            ForEach(block.children) { child in
                renderBlock(child) // recursion
            }
        }
    }
}

但是,编译器拒绝这样做,因为它需要在编译阶段确定返回类型。 是否可以在 SwiftUI 中生成这样的动态视图结构?

查看层次结构.swift:

 import SwiftUI

 @main
 struct ViewHierarchyApp: App {
    
    var body: some Scene {
        WindowGroup {
            ContentView(tree: mockData())
        }
    }
 }

 func mockData() -> [Tree] {
    let tree2: [Tree] = [Tree(id: 2, title: "2", items: [])]
    let tree1: [Tree] = [Tree(id: 1, title: "1", items: []),
                         Tree(id: 11, title: "11", items: []),
                         Tree(id: 12, title: "12", items: tree2)]
    let tree: [Tree] = [Tree(id: 0, title: "Root", items: tree1)]
    return tree
 }

Model.swift:

 class Tree: Identifiable {
    let id: Int
    let title: String
    let items: [Tree]
    
    init(id: Int, title: String, items: [Tree]) {
        self.id = id
        self.title = title
        self.items = items
    }
 }

内容视图.swift:

 struct ContentView: View {
    let tree: [Tree]
    
    var body: some View {
        VStack {
            ForEach(tree, id: \.id) { treeItem in
                TreeViewItem(item: treeItem) {
                    VStack {
                        Text("-")
                    }
                }
            }
        }
    }
 }

 struct TreeViewItem<Content: View>: View {
    let item: Tree
    let content: Content

    init(item: Tree, @ViewBuilder content: () -> Content) {
        self.item = item
        self.content = content()
    }

    var body: some View {
        VStack {
            Text(item.title)
            ForEach(item.items, id: \.id) { treeItem in
                TreeViewItem(item: treeItem) {
                    VStack {
                        Text("-")
                    } as! Content
                }
            }
        }
        content
    }
 }

Output:

在此处输入图像描述

暂无
暂无

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

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