Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
522 views
in Technique[技术] by (71.8m points)

swift - SwiftUI MVVM how to iterate and get index of array

My project is creating an ordering app, and in this screen about the menu detail, there are menu variants which users can choose / add-on, I need to iterate an array of [MenuDetailVariantGroup] and I need to get the index of the array, how do I do this? While in the for loop I also need to append a variable into a @Published var variantChosen, however if I do self.viewModel.variantChosen.append(1), it always returns an error. Below is my codes:

MenuDetailData.swift

struct MenuDetailData: Codable, Identifiable {
    let id = UUID()
    let idMenu: String
    let menuName: String
    let variantGroup: [MenuDetailVariantGroup]
}

MenuDetailVariantGroup.swift

struct MenuDetailVariantGroup: Codable, Identifiable, Hashable {
    let id = UUID()
    let variantGroupName: String
    let variant: [MenuDetailVariant]
    let limit: Int
}

MenuDetailVariant.swift

struct MenuDetailVariant: Codable, Identifiable, Hashable {
    let id = UUID()
    let variantName: String
}

MenuDetailViewModel.swift

class MenuDetailViewModel: ObservableObject, MenuDetailService {
    var apiSession: APIService
    @Published var detaildata: MenuDetailData?
    @Published var variantGroup = [MenuDetailVariantGroup]()
    @Published var variantChosen: Array<Int> = []
    
    var cancellables = Set<AnyCancellable>()
    
    init(apiSession: APIService = APISession()) {
        self.apiSession = apiSession
    }
    
    func getMenuDetail() {
        let cancellable = self.getMenuDetail()
            .sink(receiveCompletion: { result in
                switch result {
                case .failure(let error):
                    print("Handle error: (error)")
                case .finished:
                    break
                }
                
            }) { (detail) in
                self.detaildata = detail.data
                self.variantGroup = detail.data.variantGroup
        }
        cancellables.insert(cancellable)
    }
    
}

MenuDetailView

struct MenuDetailView: View {
    @ObservedObject var viewModel = MenuDetailViewModel()
    
    var body: some View {
        ForEach(self.viewModel.variantGroup, id: .self) { vg in
                /*** I Need to get the index of each iteration here, how? ***/
                VStack {
                    HStack {
                        Text(vg.variantGroupName)
                        Text(String(self.viewModel.arrVariantChoosen[0]))
                    }
                    VStack {
                        ForEach(vg.variant, id: .self) { v in
                            Text(v.variantName)
                        }
                    }
                }
                // I also need to append Int to @Published var variantChosen
                self.viewModel.variantChosen.append(1)
                // This always return error:
                // Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols
            }
        }
    }
}

This is the codes that I have tried so far but failed and return empty

// This returns blank
ForEach(0..<self.viewModel.variantGroup.count) { i in
    Text("(self.viewModel.variantGroup[i].variantGroupName)")
}

// This too returns blank
ForEach(self.viewModel.variantGroup.indices) { i in
    Text("(self.viewModel.variantGroup[i].variantGroupName)")
}

Thank you all in advance


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use enumerated to have both index and element, like

    var body: some View {
        ForEach(Array(self.viewModel.variantGroup.enumerated()), id: .1) { index, vg in
                /*** I Need to get the index of each iteration here, how? ***/
                VStack {

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...