首页 > 解决方案 > 为什么这个 SwiftUI LazyHStack 不断更新?

问题描述

我有大量URL的图像。我将文件的缩略图显示在LazyVStack. 我已经分别将“ThumbnailView”和“ThumbnailGenerator”封装在一个结构和一个类中。但是,当我运行代码时,我发现它一直在重新启动ThumbnailGenerators. 经过一番调查,我发现HStack在主视图的层次结构中删除后问题就消失了。

关于为什么会发生这种情况的任何想法。(顺便说一句,我确实用 Apple 记录了这个,但我仍然觉得我自己在这里做错了。)

我已将代码剥离到这里的基本要素,用一个简单的 sleep 语句替换缩略图生成代码,以演示实际中的错误。用 in 运行它,HStack它会连续打印出日期。把它拿出来,它按预期工作。


@main
struct ExperimentApp: App {
    var body: some Scene {
        WindowGroup {
            LazyVIssue()
                .frame(width: 200, height: 140)
                .padding(100)
        }
    }
}

struct LazyVIssue: View {
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(0..<10) { i in
                    HStack { /// <---- REMOVE THIS HSTACK AND IT WORKS
                        ThumbnailView()
                        Text("Filename \(i)")
                    }.padding()
                }
            }
        }
    }
}

struct ThumbnailView: View {
    @StateObject private var thumbnailGenerator : ThumbnailGenerator
    
    init() {
        _thumbnailGenerator = StateObject(wrappedValue: ThumbnailGenerator())
    }
    
    var body: some View {
        thumbnailGenerator.image
    }
}

final class ThumbnailGenerator: ObservableObject {
    var image : Image
    
    init() {
        print("Initiating", Date())
        image = Image(systemName: "questionmark.circle.fill")
        DispatchQueue.global(qos: .userInteractive).async { [weak self] in
            guard let self = self else { return }
            sleep(1)    /// Simulate some work to fetch  image
            self.image = Image(systemName: "camera.circle.fill")
            DispatchQueue.main.async {
                self.objectWillChange.send()
            }
        }
    }
}

标签: swiftui

解决方案


我不确定为什么会发生这种情况,但我也看到过类似这样的一些奇怪的事情发生。如果您在 ThumbnailView 初始化之外初始化 ThumbnailGenerator(),我相信问题就会消失。

init(generator: ThumbnailGenerator) {
        _thumbnailGenerator = StateObject(wrappedValue: generator)
    }

推荐阅读