gpt4 book ai didi

macos - 如何让 SwiftUI List/OutlineGroup 懒惰地用于像文件系统这样的大树?

转载 作者:行者123 更新时间:2023-12-03 17:23:28 24 4
gpt4 key购买 nike

下面是一个简单的分层演示 List在 SwiftUI 中。我正在 macOS Big Sur 上对其进行测试,但与其他 UI 工具包中的类似树组件不同,它会立即请求所有子项。所以我不能将它用于文件系统浏览器之类的东西。
有没有办法让它懒惰,这样它只要求children当 UI 元素展开时?

class Thing: Identifiable {
let id: UUID
let depth: Int
let name: String
init(_ name: String, depth: Int = 0) {
self.id = UUID()
self.name = name
self.depth = depth
}
/// Lazy computed property
var children: [Thing]? {
if depth >= 5 { return nil }
if _children == nil {
print("Computing children property, name=\(name), depth=\(depth)")
_children = (1...5).map { n in
Thing("\(name).\(n)", depth:depth+1)
}
}
return _children
}
private var _children: [Thing]? = nil
}

struct ContentView: View {
var things: [Thing] = [Thing("1"), Thing("2"), Thing("3")]
var body: some View {
List(things, children: \.children) { thing in
Text(thing.name)
}
}
}
即使初始 UI 仅显示顶部节点:

您可以在控制台中看到它要求所有内容 - 一直到树下。这是大树的性能问题。
...
Computing children property, name=3.4.4.1.4, depth=4
Computing children property, name=3.4.4.1.5, depth=4
Computing children property, name=3.4.4.2, depth=3
Computing children property, name=3.4.4.2.1, depth=4
Computing children property, name=3.4.4.2.2, depth=4
...

最佳答案

我相信这可能是 SwiftUI 中的一个错误,我希望 Apple 能够解决这个问题。同时,您可以使用以下解决方法:

struct Node {
var id: String
var value: String
var children: [Node]?
}

struct LazyDisclosureGroup: View {
let node: Node
@State var isExpanded: Bool = false

var body: some View {
if node.children != nil {
DisclosureGroup(
isExpanded: $isExpanded,
content: {
if isExpanded {
ForEach(node.children!, id: \.self.id) { childNode in
LazyDisclosureGroup(node: childNode)
}
}
},
label: { Text(node.value) })
} else {
Text(node.value)
}
}
}

struct ContentView: View {
let node = Node(
id: "a",
value: "a",
children: [Node(id: "b", value: "b", children: nil),
Node(id: "c", value: "c", children: nil)])
var body: some View {
List {
LazyDisclosureGroup(node: node)
}
}
}
我不知道这是否是最佳实践,但解决方法使用了 DisclosureGroup 的观察结果。当它在 List 内时的“通知” .两者的结合产生相同的视觉结构和行为。

关于macos - 如何让 SwiftUI List/OutlineGroup 懒惰地用于像文件系统这样的大树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64236386/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com