数组大小更改后如何刷新ForEach显示元素的数量(SwiftUI,Xcode 11 Beta 5)

时间:2019-08-02 17:16:29

标签: swift xcode swiftui xcode11

我试图实现一个视图,该视图可以在内容数组的大小更改时更改显示项的数量(由ForEach循环创建),就像购物应用可能在用户拉动刷新后更改其可用项的数量一样

这是到目前为止我尝试过的一些代码。如果我没记错的话,这些代码适用于Xcode beta 4,但适用于beta 5:

  • 如果数组的大小增加,则循环仍将显示元素的原始数量
  • 数组的大小减小将导致索引超出范围错误

代码:

import SwiftUI

struct test : View {
    @State var array:[String] = []
    @State var label = "not pressed"
    var body: some View {
        VStack{
            Text(label).onTapGesture {
                self.array.append("ForEach refreshed")
                self.label = "pressed"
            }
            ForEach(0..<array.count){number in
                Text(self.array[number])
            }
        }
}
}

#if DEBUG
struct test_Previews: PreviewProvider {
    static var previews: some View {
        test()
    }
}
#endif

我一般是SwiftUI和GUI编程的新手,只是感觉每个内容都是在启动时定义的,因此之后真的很难进行更改(例如:在用户导航离开并返回后重置视图) 。对于循环问题的解决方案或使视图更具动态性的任何提示,将不胜感激!

1 个答案:

答案 0 :(得分:5)

Beta 5发行说明说:

  

Int与可识别协议的追溯一致性为   删除。更改任何依赖于此一致性的代码以通过   .self到相关初始化程序的id参数。不变   Int范围将继续被接受:

     
List(0..<5) {
   Text("Rooms")
}
     

但是,您不应传递在运行时更改的范围。如果你   使用在运行时更改的变量来定义范围,列表   根据初始范围显示视图,并忽略任何   随后对该范围进行更新。

您应该将ForEach更改为接收数组,而不是范围。最好是Identifiable数组,以避免使用\.self。但是根据您的目标,这仍然可以工作:

import SwiftUI

struct ContentView : View {
    @State var array:[String] = []
    @State var label = "not pressed"
    var body: some View {
        VStack{
            Text(label).onTapGesture {
                self.array.append("ForEach refreshed")
                self.label = "pressed"
            }
            ForEach(array, id: \.self) { item in
                Text(item)
            }
        }
    }
}

或者如 rob mayoff 所建议,如果需要索引:

struct ContentView : View {
    @State var array:[String] = []
    @State var label = "not pressed"
    var body: some View {
        VStack{
            Text(label).onTapGesture {
                self.array.append("ForEach refreshed")
                self.label = "pressed"
            }
            ForEach(array.indices, id: \.self) { index in
                Text(self.array[index])
            }
        }
    }
}```