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

Posted

技术标签:

【中文标题】如何在数组大小更改后刷新 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) 【发布时间】:2019-08-02 17:16:29 【问题描述】:

我正在尝试实现一个视图,如果内容数组的大小发生变化,该视图可以更改显示项目的数量(由 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】:

Beta 5 发行说明说:

Int 对 Identifiable 协议的追溯一致性是 删除。更改任何依赖此一致性的代码以通过 .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])
            
        
    
```

【讨论】:

或者ForEach(array.indices, id: \.self)如果你需要数组索引。 我总是忘记.indices。谢谢,我更新了答案。 Will ForEach(array.indices, id: \.self) 当数组改变时更新视图? 如果 ForEach 中的视图需要绑定,所有这些解决方案都将不起作用。

以上是关于如何在数组大小更改后刷新 ForEach 显示元素的数量(SwiftUI,Xcode 11 Beta 5)的主要内容,如果未能解决你的问题,请参考以下文章

将元素附加到数组后,它应该显示更多元素

Swift/iOS:UIPicker 显示在以编程方式更改数据源后点击后才会刷新

如何在excel批量更改单元格类型后的批量刷新显示?

C#中foreach用法

如何使用ajax更改事件对象后刷新fullcalendar v4

更改 FriendlyName 注册表值后如何强制 Windows 设备管理器刷新设备名称显示