SwiftUI SceneDelegate - contentView Отсутствует аргумент для параметра index в вызове - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь создать список, используя ForEach и NavigationLink массива данных.

Я считаю, что мой код (см. Конец сообщения) верен, но моя сборка не выполняется из-за «Отсутствует аргумент для параметр 'index' в вызове "и переносит меня в SceneDelegate.swift, в место, куда мне раньше не приходилось рисковать.

// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()

Я могу получить код для запуска, если я изменю; 1007 *

, но тогда все мои ссылки содержат одни и те же данные, что имеет смысл, поскольку я называю позицию индекса.

Я пробовал, index: self.index (это то, что я использую в своем NavigationLink) и получите другое сообщение об ошибке - Невозможно преобразовать значение типа '(Any) -> Int' в ожидаемый тип аргумента 'Int'

Ниже приведены фрагменты моего кода для справки;

struct HabitItem: Identifiable, Codable {
    let id = UUID()
    let name: String
    let description: String
    let amount: Int
}

class HabitsList: ObservableObject {
    @Published var items = [HabitItem]()
}

struct ContentView: View {
    @ObservedObject var habits = HabitsList()
    @State private var showingAddHabit = false
    var index: Int
        
    var body: some View {
        NavigationView {
            List {
                ForEach(habits.items) { item in
                    NavigationLink(destination: HabitDetail(habits: self.habits, index: self.index)) {
                        HStack {
                            VStack(alignment: .leading) {
                                Text(item.name)
                                    .font(.headline)
                                Text(item.description)
                            }
                        }
                    }
                }
            }
        }
    }
}

struct HabitDetail: View {
    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var habits: HabitsList

    var index: Int
    
    var body: some View {
        NavigationView {
            Form {
                Text(self.habits.items[index].name)
            }
        }
    }
}

1 Ответ

1 голос
/ 10 июля 2020

Вероятно, вам не нужно передавать весь ObservedObject в HabitDetail.

Достаточно передать только HabitItem:

struct HabitDetail: View {
    @Environment(\.presentationMode) var presentationMode
    let item: HabitItem

    var body: some View {
        // remove `NavigationView` form the detail view
        Form {
            Text(item.name)
        }
    }
}

Тогда вы можете измените свой ContentView:

struct ContentView: View {
    @ObservedObject var habits = HabitsList()
    @State private var showingAddHabit = false

    var body: some View {
        NavigationView {
            List {
                // for every item in habits create a `linkView`
                ForEach(habits.items, id:\.id) { item in
                    self.linkView(item: item)
                }
            }
        }
    }
    
    // extract to another function for clarity
    func linkView(item: HabitItem) -> some View {
        // pass just a `HabitItem` to the `HabitDetail`
        NavigationLink(destination: HabitDetail(item: item)) {
            HStack {
                VStack(alignment: .leading) {
                    Text(item.name)
                        .font(.headline)
                    Text(item.description)
                }
            }
        }
    }
}
...