首页 > 解决方案 > 使用带有异步加载行并使用 GeometryReader 布局的 List 时的竞争条件

问题描述

这是SwiftUI 中内容拥抱优先级行为的后续问题。

我有一个列表,其中每一行都包含异步加载的图像,它的高度是使用 GeometryReader 设置的。完整代码在这里

struct CountryCell: View {
    let country: Country

    @State var childSize: CGSize = .init(width: 0, height: 50)

    var body: some View {
        HStack {
            AsyncImage(url: Endpoints.flag(countryCode: country.flagCode).url, placeholder: Image("flag"))
                .aspectRatio(contentMode: .fit)
                .frame(width: DeviceMetrics.size.width * 0.25, height: self.childSize.height)
            VStack(alignment: .leading, spacing: 5) {
                Text("Country: ").bold() + Text(self.country.name)
                Text("Capital: ").bold() + Text(self.country.capital)
                Text("Currency: ").bold() + Text(self.country.currency)
            }
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
            .background(
                GeometryReader { proxy -> AnyView in
                    DispatchQueue.main.async {
                        self.childSize = proxy.size
                    }
                    return AnyView(Color.clear)
            })
        }
    }
}

运行它,图像不会替换占位符(可能会随机显示十分之一),尽管发出了网络请求。我想不通,但有一种预感,这是 GeometryReader 和 AsyncImage 在触发布局期间的竞争条件。如果您更换:

.frame(width: DeviceMetrics.size.width * 0.25, height: self.childSize.height)

和:

.frame(width: DeviceMetrics.size.width * 0.25)

然后图像将正确显示。同样,如果您注释掉 GeometryReader,事情也将开始工作。

任何提示将不胜感激。

标签: swiftuiswiftui-list

解决方案


推荐阅读