SwiftUI ForEach无法在滚动视图中正确更新

时间:2019-12-13 04:19:25

标签: ios swiftui

我有一个带有HStack和其中的ForEach的SwiftUI ScrollView。 ForEach基于ObservableObject的Publisher变量构建而成,因此当添加/删除/设置项时,它将在视图中自动更新。但是,我遇到了多个问题:

  1. 如果数组开始为空并添加了项,则不会显示它们。
  2. 如果数组中包含一些项目,我可以添加一个项目,它将显示该项目,但是添加更多项目则不会。

如果我只有一个带ForEach的HStack,则不会发生上述两个问题。一旦它在ScrollView中,我就会遇到问题。

下面是可以粘贴到Xcode SwiftUI Playground中的代码,以演示该问题。在底部,您可以取消注释/注释不同的行以查看两个不同的问题。

如果取消注释问题1,然后单击任一按钮,您将只会看到HStack更新,而在ScrollView中却看不到HStack。 您会看到这些项目的初始化打印语句。 / p>

如果取消对问题2的注释,然后单击任一按钮,您应该会看到第二次单击ScrollView更新,但是如果继续单击,它将不会更新-即使仅HStack仍会更新并进行初始化打印语句将输出ScrollView项。

results

这是一个错误吗?我想念什么吗?我是iOS开发的新手。我确实尝试将实际的项目设置/附加包装在DispatchQueue.main.async中,但这并没有做任何事情。

也许也没有关系,但是如果您单击足够多的按钮,应用程序似乎就会崩溃。

3 个答案:

答案 0 :(得分:4)

碰到同样的问题。使用空数组检查和不可见的HStack解决了

ScrollView(showsIndicators: false) {
    ForEach(self.items, id: \.self) { _ in
        RowItem()
    }

    if (self.items.count == 0) {
        HStack{
            Spacer()
        }
    }
}

答案 1 :(得分:1)

ScrollView在观察到的空容器中是已知的行为-它需要一些内容(初始内容)来计算初始大小,因此以下内容可以解决您的代码行为

@Published var items: [String] = [""]

通常,在这种情况下,我更喜欢在数组中存储一些“易于检测的初始值”,当第一个“真实模型值”出现时将其删除,而在最后一个消失时再次添加。希望这会有所帮助。

答案 2 :(得分:0)

为了提高可读性,还因为答案对我不起作用。我建议对@ TheLegend27答案进行如下修改:

if self.items.count != 0 {

   ScrollView(showsIndicators: false) {
       ForEach(self.items, id: \.self) { _ in
           RowItem()
       }
   }

}