метод .enumerated() не работает с массивом

#swiftui

#swiftui

Вопрос:

Я передаю данные в ForEach, и у меня не было проблем, пока я не использовал этот .enumerated() метод. Я получил сообщение об ошибке, которое:

  1. Общая структура ‘ForEach’ требует, чтобы ‘EnumeratedSequence<[String]>’ соответствовала ‘RandomAccessCollection’
  2. Тип ‘EnumeratedSequence<[String]>.Element’ (он же ‘(offset: Int, element: String)’) не может соответствовать ‘Hashable’; только типы struct / enum / class могут соответствовать протоколам

Что касается первой ошибки, то вы увидите в коде, который я просто передаю в массив. Поэтому я не понимаю эту ошибку.

Что касается второй ошибки, я не уверен в этом.

Данные, передаваемые в массив, поступают из 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()
    }
}
 

Текст

Ответ №1:

enumerated() Возвращает последовательность кортежей, которые вы можете преобразовать в массив, например

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

Ответ №2:

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
}
 

потому что он также работает с нецелыми индексами.

Комментарии:

1. Это помогло, мне любопытно, на что ссылается ключевой путь «1» для идентификатора параметра??

2. Он ссылается на второй элемент кортежа, который является элементом массива. Он должен Hashable работать