Выбор средства выбора «nil» недействителен и не имеет тега

У меня есть приложение, которое хранит данные о транзакциях с классификацией категорий. Имена категорий могут быть выбраны из пула вложенных имен или добавлены посредством ввода текста. Проблема, с которой я сталкиваюсь, связана с выбором категорий из пула имен.

Структура GetCategory предназначена для выбора категории транзакции. Например, покупка некоторых товаров в продуктовом магазине может быть отнесена к категории продуктов питания. Возвращаемое значение этой структуры — вернуть строку имени категории.

При выборе категории появляется предупреждающее сообщение:

Процесс выбора категории транзакции выдает ошибку Picker: выбор «nil» недействителен и не имеет связанного тега, это даст неопределенные результаты.

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

При выборе флага используемой категории catInuse устанавливается значение true.

struct GetCategory: View {
    @EnvironmentObject var categories: Categories

    @Binding var entryCat: CatModel?

    var categoryList: [CatModel] {
        return categories.catItem.filter(\.catInUse)
    }

    var body: some View {

        ForEach(categoryList) { list in
            Text(list.catName)
        }

        Section(header: Text("Select Category")) {
            Picker("", selection: $entryCat) {

                ForEach(categoryList) { category in
                    Text(category.catName)
                        .tag(Optional(category.id))
                }
            }.pickerStyle(MenuPickerStyle())
        }
        if let gotName = entryCat {
            Text("Selected Category is \(gotName.catName)")
                .padding(.top, 15)
        }
    }
}

Отвечает ли это на ваш вопрос? Выбор средства выбора "0" недействителен и не имеет связанного тега

workingdog support Ukraine 21.02.2023 05:55

Каждый элемент Picker должен иметь связанный тег. Если вы хотите состояние «Ничего не выбрано», вам нужно добавить пункт меню для Nothing selected, который также может отображать пустую строку. Если нет, вы должны назначить элемент по умолчанию свойству entryCat.

vadian 21.02.2023 06:59

Мне не нужен ничего не выбранный пункт меню

Galen Smith 21.02.2023 16:37

Привет @workingDog: Спасибо за помощь. GetCategory() прекрасно работает, поскольку вы создали его без каких-либо предупреждений, но если я добавлю строку if category.catInUse вокруг текстовой строки, я получаю предупреждение консоли «Выборщик: выбор «CatModel (catNum:, catName: «жилье», catTotal: , catBudget:, catPix:, catInUse: false, catCustom:)" недействителен и не имеет связанного тега, это даст неопределенные результаты». Категория «Проживание» — первая из 14 доступных категорий для использования в приложении, но в данном случае пользователь не выбрал категорию «Проживание».

Galen Smith 22.02.2023 03:13

Мне не нужен ничего не выбранный пункт меню. Средство выбора должно отображать что-то, если ничего не выбрано, по крайней мере, пустую строку, которая технически является пустым пунктом меню. Альтернативой, как я уже сказал, является назначение значения по умолчанию или скрытие средства выбора. Таким образом, в отличие от selection свойства List, свойство entryCat должно быть необязательным.

vadian 22.02.2023 08:48

Привет @vadian. Приложение разработано таким образом, что если из пула имен категорий не выбрано ни одной категории, появится сообщение, указывающее, что категории необходимо выбрать, и запрещающее ввод транзакции. После выбора группы рабочих категорий эта группа появится при вводе транзакции в выпадающем списке. Предупреждение, которое я вижу в консоли, возникает, когда первая категория в большом пуле не выбрана и не отображается среди рабочих категорий.

Galen Smith 22.02.2023 17:38
Типы данных JavaScript
Типы данных JavaScript
В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных...
Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)
Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к...
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и...
Введение в раздел "Заголовок" в HTML
Введение в раздел "Заголовок" в HTML
Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не...
0
6
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поразмыслив, вот еще один подход, который использует entryCat: CatModel? и проверяет его не nil перед отображением Picker. Таким образом, опция выбора nil невозможно.

Приведенный ниже код — это всего лишь пример кода, который у меня работает, т. е. он не выдает предупреждений. Вам необходимо отрегулировать код в соответствии с вашими потребностями.

struct CatModel:  Codable, Identifiable, Hashable {
    var id = UUID()
    var catNum: Int         // used by setup categories
    var catName: String     // category name
    var catTotal: Double    // category total
    var catBudget: Double   // category budget
    var catPix: String      // sf symbol
    var catInUse: Bool      // catInUse: true = category in use
    var catCustom: Bool     // true = custom category (can be deleted)
}

struct ContentView: View {
    @StateObject var categories = Categories()
    @State var entryCat: CatModel? // <-- here
    
    var body: some View {
        VStack (spacing: 55) {
            Text("Selected is \(entryCat?.catName ?? "no selection")") // <-- here for testing
            GetCategory(entryCat: $entryCat)
                .environmentObject(categories)
            
            // for testing, change some catInUse to true
            Button("click to test") {
                // change the first false catInUse to true
                if let first = categories.catItem.firstIndex(where: {!$0.catInUse}) {
                    categories.catItem[first].catInUse = true
                    entryCat = categories.catItem[first]
                }
            }
        }
    }
}

class Categories: ObservableObject {

    // this is for testing purpose
    @Published var catItem = [
        CatModel(catNum: 0, catName: "Cat A", catTotal: 0.0, catBudget: 0, catPix: "a.circle", catInUse: false, catCustom: true),
        CatModel(catNum: 1, catName: "Cat B", catTotal: 0.0, catBudget: 0, catPix: "b.circle", catInUse: true, catCustom: true),
        CatModel(catNum: 2, catName: "Cat C", catTotal: 0.0, catBudget: 0, catPix: "c.circle", catInUse: true, catCustom: true)
        //..... more  CatModel
    ]
    
    //..... more code
}

struct GetCategory: View {
    @EnvironmentObject var categories: Categories
    
    @Binding var entryCat: CatModel? // <-- here

    var categoryList: [CatModel] {
        categories.catItem.filter(\.catInUse)
    }
    
    var body: some View {
        VStack {
            Section(header: Text("Select Category")) {
                if entryCat != nil  {  // <-- here
                    Picker("", selection: $entryCat) {
                        ForEach(categoryList) { category in
                            Text(category.catName).tag(category as CatModel?) // <-- here, needed
                        }
                    }.pickerStyle(MenuPickerStyle())
                } else {
                    Text("No selections available").foregroundColor(.red) // <-- here is entryCat == nil
                }
            }
        }
        .onAppear {
            // <-- try to make entryCat not nil, for testing if needed
            if entryCat == nil  {
                if let theEntryCat = categoryList.first {
                    entryCat = theEntryCat
                }
            }
        }
    }
}

Я не понимаю, что вы делаете с категориями класса. Каждая запись имеет значения catName, catTotal, catBudget, catPix, catInUse и catCustom. Я должен добавить все это к издателю? В ContentView @State entryCat показывает ошибку «Отсутствуют аргументы для параметров catTotal, catBudget и т. д. Разница между вашим кодом и моим заключается в классе.

Galen Smith 21.02.2023 17:15

Обновил мой ответ другим подходом, который использует CatModel?. Дайте мне знать, если это то, что вы ищете.

workingdog support Ukraine 22.02.2023 07:44

Другие вопросы по теме