【问题标题】:.enumerated() method not working on array.enumerated() 方法不适用于数组
【发布时间】:2021-01-12 19:11:19
【问题描述】:

我将数据传递给 ForEach 并且在使用 .enumerated() 方法之前没有任何问题。我得到的错误是:

  1. 通用结构 'ForEach' 要求 'EnumeratedSequence' 符合 'RandomAccessCollection'

  2. Type 'EnumeratedSequence.Element' (aka '(offset: Int, element: String)') 不能符合'Hashable';只有结构/枚举/类类型可以符合协议

至于第一个错误,您将在代码中看到我只是在数组中传递。所以我不明白这个错误。

至于第二个错误我不确定。

传递到数组中的数据是从 UserDefaults 提供的,您将在下面的代码中看到。

import SwiftUI

struct ContentView: View {
    
    @State private var name = ""
    @State private var myArray = [String]()
    @State private var isShowing = false
    @State private var actionSheet = false
    let defaults = UserDefaults.standard
   
    var body: some View {
        VStack {
            Spacer()
            TextField("Insert name", text: $name)
                .padding()
            ScrollView(.horizontal) {
                HStack {
                    ForEach(myArray.enumerated(), id: \.self) { index, name in
                        Circle()
                            .onTapGesture {
                                self.actionSheet.toggle()
                            }
                            .frame(width: 50, height: 50)
                            .actionSheet(isPresented: $actionSheet) {
                                ActionSheet(title: Text("Titles"), message: Text("This is the message"), buttons: [
                                                .default(Text("Delete item")){
                                                    var loaded =  defaults.stringArray(forKey: "myData")
                                                    
                                                }
                                ])
                            }
                    }
                }.padding()
                
            }
            Text(String(myArray.count))
                .font(.system(size: 30, weight: .black, design: .rounded))
                .foregroundColor(.green)
            VStack {
                Button(action: {self.isShowing.toggle() }){ Text("Show")}
                if isShowing {
                    ForEach(myArray, id: \.self) { name in
                    Text(name)
                    }
                }
            }.animation(.interactiveSpring())
            Spacer()
            
            HStack {
                Button(action: {
                   
                    
                }){
                    Text("Delete")
                        .fontWeight(.bold)
                        .padding()
                        .foregroundColor(.white)
                        .background(Color.red)
                        .cornerRadius(10)
                }
                Button(action: {
                    myArray.append(name)
                    defaults.set(myArray, forKey: "myData")
                    self.name = ""
                }){
                    Text("Save")
                        .fontWeight(.bold)
                        .padding()
                        .foregroundColor(.white)
                        .background(Color.blue)
                        .cornerRadius(10)
                }
               

            }
           

        }.onAppear {
            guard let loaded = defaults.object(forKey: "myData") as? [String] else {
                return
            }
            self.myArray = loaded
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    ForEach 需要一个符合RandomAccessCollection 的类型,但Array.enumerated() 返回一个EnumeratedSequence<[Element]>,它只符合Sequence

    您可以将其包装在Array 中以获取符合RandomAccessCollection 的数组:

    ForEach(Array(myArray.enumerated()), id: \.1) { (n, element) in
    }
    

    我个人喜欢用zip

    ForEach(zip(myArray.indices, myArray), id: \.1) { (index, element) in
    }
    

    因为它也适用于非整数索引。

    【讨论】:

    • 成功了,我很好奇,参数id的keypath“1”是什么,指的是什么??
    • 指的是元组的第二个元素,也就是数组的元素。工作应该是Hashable
    【解决方案2】:

    enumerated()返回元组序列,可以转换成数组,比如

    HStack {
        ForEach(Array(myArray.enumerated()), id: \.1) { index, name in
            Circle()
    

    【讨论】:

    • 谢谢,虽然我很困惑为什么我需要将数组转换为数组:/
    猜你喜欢
    • 2023-02-06
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多