如何在 SwiftUI 的 ForEach 循环中增加状态?

Posted

技术标签:

【中文标题】如何在 SwiftUI 的 ForEach 循环中增加状态?【英文标题】:How to increment a state in a ForEach loop in SwiftUI? 【发布时间】:2020-08-12 14:40:37 【问题描述】:

我需要增加 genNum 变量并将其传递给 ForEach 循环中的另一个结构。我的代码正在正确编译,但无法在模拟和画布中预览它。获取“无法在此文件中预览”。我遇到的另一个错误是“RemoteHumanReadableError:无法完成操作。(BSServiceConnectionErrorDomain 错误 3。)”。

BSServiceConnectionErrorDomain (3): ==BSErrorCodeDescription: 操作失败

import SwiftUI

@available(ios 14.0, *)
struct CategoryView: View 
    @State var genNum: Int = -1
    
    var categories: [Int: [PokemonData]] 
        Dictionary(
            grouping: pokemonData,
            by:  $0.generation 
        )
    
    
    var columns: [GridItem] = [
        GridItem(.fixed(170)),
        GridItem(.fixed(170))
    ]

    var body: some View 
        NavigationView 
            ScrollView 
                LazyVGrid(columns: columns) 
                    ForEach(categories.keys.sorted(), id: \.self)  key in
                        CategoryCard(genNum: self.increment()) // <--- Having problem with this line
                    
                
                AllCard()
                    .padding(.horizontal, 15)
                    .padding(.bottom, 20)
            
            .navigationTitle("Categories")
        
    
    
    // Function to increment the state value
    func increment() -> Int 
        self.genNum += 1
        let i = genNum
        return i
    

【问题讨论】:

为什么在视图渲染阶段需要它? 【参考方案1】:

如果您只想将值从 0 传递到 count-1 到您的 CategoryCard() 初始化程序,您可以使用 enumerated() 函数。该函数将一个数组作为输入并返回一个元组数组,其中第一项是数组索引,第二项是原始数组中的元素。

这段代码,例如:

let array = ["zero", "one", "two", "three"]

array.enumerated().forEach  (index, string) in
    print (index, string)

输出以下内容:

0 zero
1 one
2 two
3 three

所以你可以像这样重写你的代码:

            LazyVGrid(columns: columns) 
                
                ForEach(categories.keys.sorted().enumerated(), id: \.self)  (index, key) in
                    CategoryCard(genNum: index) // <--- Having problem with this line
                
            

(免责声明:我还没有使用过 SwiftUI,所以我并不完全清楚 ForEach 在你的 LazyGrid 中做了什么)

【讨论】:

在 ForEach 循环行中出现此错误: 1. 通用结构 'ForEach' 要求 'EnumeratedSequence.Keys.Element]>'(又名 'EnumeratedSequence>') 符合 'RandomAccessCollection' 2. 类型 'EnumeratedSequence.Keys.Element]>.Element' (aka '(offset: Int, element: Int)') 不能符合“可哈希”;只有结构/枚举/类类型可以符合协议

以上是关于如何在 SwiftUI 的 ForEach 循环中增加状态?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何在 ForEach 循环中不显示“case none”

如何在 SwiftUI 的 foreach 循环中设置切换状态

SwiftUI:如何使用 ForEach 循环使用各种代码的各种结构?

Swiftui 如何在 foreach 循环中对整行使用 Tap Gesture

在 ForEach 循环中绑定时,如何阻止 SwiftUI TextField 失去焦点?

SwiftUI:如何根据 Picker 的值更新 ForEach 循环的范围