SwiftUI 列出屏幕外元素中的问题

SwiftUI List issues in offscreen elements

我整理了一个快速文件夹浏览器来查看子文件夹中的一堆图像。基本上,给定一个路径,它会查找文件夹并为您提供一个按钮来展开文件夹并显示其中的图像。

下面是我整理的代码。但是,如果 List 单元格绘制在屏幕外,则 Button 一旦滚动到视图中就永远不会显示。任何人都可以复制这个吗?我如何解决它?这只是 SwiftUI 中的一个错误吗?

编辑:为清楚起见,这是 macOS Catalyst。

这里是使用列表的地方:

List(folderurls, id: \.self) { url in
    ListImageViewer(url: url)
}

这里是 ListImageViewer 的完整代码:

struct ListImageViewer: View {
    var url: URL
    @State var expanded: Bool = false {
        didSet {
            if expanded {
                self.coordinator.refreshListing(for: self.url)
            } else {
                self.coordinator.contents = []
            }
        }
    }
    @ObservedObject var coordinator = FolderListingCoordinator()

    var body: some View {
        VStack {
            HStack {
                Button(action: {
                    self.expanded.toggle()
                }) { Text(self.expanded ? "Collapse" : "Expand") }
                Text("\(url.lastPathComponent)")
            }

            HStack {
                ForEach(coordinator.contents, id: \.self) { url in
                    ImageView(url: url)
                }
                Spacer()
            }
        }
    }
}

我已经针对类似问题提交了错误。我发现的一种解决方法是向适用于其子视图的 VStack 添加修饰符。对我来说,我在绘制 TextFields 时遇到了问题,所以我更改了以下内容:

var body: some View {
    Section(header: Text("Row \(row)")) {
        HStack(alignment: .center, spacing: 20) {
            Text("Name")
            Spacer()
            TextField("Name", text: $name)
                .frame(maxWidth: 120)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
        HStack(alignment: .center, spacing: 20) {
            Toggle("Fixed", isOn: $isFixed)
        }
    }
}

var body: some View {
    Section(header: Text("Row \(row)")) {
        HStack(alignment: .center, spacing: 20) {
            Text("Name")
            Spacer()
            TextField("Name", text: $name)
                .frame(maxWidth: 120)                    
        }
        HStack(alignment: .center, spacing: 20) {
            Toggle("Fixed", isOn: $isFixed)
        }
    }.textFieldStyle(RoundedBorderTextFieldStyle())
}

您可以通过向包含的 VStack 添加一些样式来找到类似的解决方法。

好吧,我偶然发现了这个问题的答案。一旦我为列表中的项目提供 .id 修饰符,它们就会在屏幕外停止错误渲染。

ListImageViewer(url: url)
    .id(url)

性能较差,但总算达到预期效果