SwiftUI ForEach 的字典识别问题

Posted

技术标签:

【中文标题】SwiftUI ForEach 的字典识别问题【英文标题】:SwiftUI ForEach of dictionary identified issue 【发布时间】:2019-06-20 15:07:44 【问题描述】:

使用下面给定的代码,我尝试遍历字典 wordList,但由于问题 Instance method 'identified(by:)' requires that '(key: Int, value: [String : String])' conform to 'Hashable' 而失败。

所以我的猜测是我必须以某种方式将协议Hashable 应用到字典的Int,或者可能有另一种解决方案涉及.identified(by:) 的使用

非常感谢您的帮助!

struct ContentView: View 
    @State var wordOrder = ["DE", "EN"]

    let wordList: [Int: [String: String]] = [
        0: [
            "DE": "Hallo Welt",
            "EN": "hello world"
        ],
        1: [
            "DE": "Tschüss",
            "EN": "goodbye"
        ],
        2: [
            "DE": "vielleicht",
            "EN": "maybe"
        ]
    ]

    var body: some View 
        Group 
            NavigationView 
                List() 
                    ForEach(wordList.identified(by: \.self))  wordListEntry in
                        let lang1 = wordListEntry[wordOrder[0]]
                        let lang2 = wordListEntry[wordOrder[1]]
                        WordRow(lang1, lang2)
                    
                
                .navigationBarTitle(Text("Alle Wörter"))
            
        
    

【问题讨论】:

SwiftUI iterating through dictionary with ForEach的可能重复 不一定。我也检查了另一个问题,这表明了一种可行的方法。但是这个答案建议为键创建一个数组,为值创建一个数组。我相信上面提出的问题可能有解决方案,不需要那些“回避”。 但是你如何克服Dictionary 是无序的这一事实,但你又试图捕捉数组何时重新排序?如果Hashable 所做的只是“识别”唯一的数组元素,那么您已经使用 Dictionary 键拥有了它!无论如何,您将需要至少一个数组用于List() 订单。 【参考方案1】:

看来你有误会。根据您发布的代码,我猜您认为迭代字典会迭代字典中的值。但这不是字典迭代的工作原理。

当您遍历字典时,您会收到 pairs。每对都包含一个键和字典中的相应值。在您的代码中,wordListEntry 的类型是 (key: Int, value: [String: String]),它的第一个元素是 key,类型为 Int,第二个元素是 value,类型为 [String: String]

我认为您只想遍历字典的键,然后在 ForEach 正文中查找相应的值,如下所示:

ForEach(wordList.keys.sorted().identified(by: \.self))  key in
    let lang1 = wordListEntry[wordOrder[0]]
    let lang2 = wordListEntry[wordOrder[1]]
    return WordRow(lang1, lang2)

【讨论】:

谢谢。这是要走的路:) 再问一个问题:我注意到您删除了 ForEach 循环中的变量。我的代码也因此失败,因为似乎不可能在里面使用 var。有解决办法吗? 我认为ForEach 使用了@ViewBuilder,它(从 Xcode 11 beta 2 开始)不允许局部变量。然而,我错了。但由于闭包不是单个表达式,因此您必须显式使用 return 语句。我已经更新了我的答案。 哦,现在这是一个严重的限制。希望这将很快得到改善。感谢您更新您的答案! 你能帮我解决这个问题吗***.com/questions/56814962/…【参考方案2】:

为最新的 swift UI 更新:

    ForEach(wordList.keys.sorted(), id: \.self)  key in
    let lang1 = wordListEntry[wordOrder[0]]
    let lang2 = wordListEntry[wordOrder[1]]
    return WordRow(lang1, lang2)

【讨论】:

以上是关于SwiftUI ForEach 的字典识别问题的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 使用 List 和 Foreach 遍历字典中的键并创建列表视图

SwiftUI - 将 ForEach 与不符合可识别/可散列的绑定数组一起使用

视图模型数组上的 ForEach 循环问题导致 Xcode 编译错误 - SwiftUI

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

SwiftUI ListView 没有访问 ForEach 循环

SwiftUI:删除行时使用 Array/Index 的 ForEach 崩溃