SwiftUI ScrollView无法更新?

时间:2019-11-13 05:35:54

标签: swiftui

目标

获取数据以显示在scrollView

预期结果

data shown in scrollview

实际结果

a blank view

替代

使用List,但不灵活(无法删除分隔符,不能有多列)

代码

struct Object: Identifiable {
    var id: String
}

struct Test: View {
    @State var array = [Object]()

    var body: some View {
//        return VStack { // uncomment this to see that it works perfectly fine
        return ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

5 个答案:

答案 0 :(得分:21)

解决这个问题的一种不太聪明的方法是将ScrollView包含在IF语句中,该IF语句检查数组是否为空

if !self.array.isEmpty{
     ScrollView(.vertical) {
          ForEach(array) { o in
               Text(o.id)
          }
     }
}

答案 1 :(得分:1)

预期的行为发生在Xcode 11.1上,但没有发生在Xcode 11.2.1

我在frame上添加了ScrollView修饰符,使ScrollView出现

struct Object: Identifiable {
    var id: String
}

struct ContentView: View {
    @State var array = [Object]()

    var body: some View {
        ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .frame(height: 40)
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

答案 2 :(得分:1)

我发现,如果状态初始化为某个值而不是空数组,则可以按预期工作(Xcode 11.2)。在这种情况下,更新工作正常,初始状态无效。

struct TestScrollViewOnAppear: View {
    @State var array = [Object(id: "1")]

    var body: some View {
        ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

答案 3 :(得分:1)

从paulaysabellemedina借来的时候,我想到了一个小助手视图,该视图以我期望的方式处理事情。

struct ScrollingCollection<Element: Identifiable, Content: View>: View {
    let items: [Element]
    let axis: Axis.Set
    let content: (Element) -> Content

    var body: some View {
        Group {
            if !self.items.isEmpty {
                ScrollView(axis) {
                    if axis == .horizontal {
                        HStack {
                            ForEach(self.items) { item in
                                self.content(item)
                            }
                        }
                    }
                    else {
                        VStack {
                            ForEach(self.items) { item in
                                self.content(item)
                            }
                        }
                    }
                }
            }
            else {
                EmptyView()
            }
        }
    }
}

答案 4 :(得分:0)

我发现一个有问题的解决方法是在scrollView内添加一个“不可见的” Rectangle,并将width设置为大于{{1}中数据宽度的值}

scrollView