如何在数组大小更改后刷新 ForEach 显示元素的数量(SwiftUI,Xcode 11 Beta 5)
How to refresh number of ForEach's displaying elements after array's size changes (SwiftUI, Xcode 11 Beta 5)
我正在尝试实现一个视图,该视图可以在内容数组的大小发生变化时更改显示项目的数量(由 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 编程的新手,感觉每个内容都是在启动时定义的,之后很难进行更改(例如:在用户导航离开后重置视图 return 到它)。循环问题的解决方案或使视图更具动态性的任何提示将不胜感激!
Beta 5 发行说明说:
The retroactive conformance of Int to the Identifiable protocol is
removed. Change any code that relies on this conformance to pass
.self to the id parameter of the relevant initializer. Constant
ranges of Int continue to be accepted:
List(0..<5) {
Text("Rooms")
}
However, you shouldn’t pass a range that changes at runtime. If you
use a variable that changes at runtime to define the range, the list
displays views according to the initial range and ignores any
subsequent updates to the range.
您应该更改 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])
}
}
}
}```
我正在尝试实现一个视图,该视图可以在内容数组的大小发生变化时更改显示项目的数量(由 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 编程的新手,感觉每个内容都是在启动时定义的,之后很难进行更改(例如:在用户导航离开后重置视图 return 到它)。循环问题的解决方案或使视图更具动态性的任何提示将不胜感激!
Beta 5 发行说明说:
The retroactive conformance of Int to the Identifiable protocol is removed. Change any code that relies on this conformance to pass .self to the id parameter of the relevant initializer. Constant ranges of Int continue to be accepted:
List(0..<5) { Text("Rooms") }
However, you shouldn’t pass a range that changes at runtime. If you use a variable that changes at runtime to define the range, the list displays views according to the initial range and ignores any subsequent updates to the range.
您应该更改 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])
}
}
}
}```