Ссылаясь на метод экземпляра onChange(of:perform:) на Optional, требуется, чтобы Binding соответствовал Equatable

У меня есть следующий SwiftUI View (извлеченный и упрощенный код):

struct MyView<T : Hashable>: View {
    private let selection: Binding<T?>?

    init(selection: Binding<T?>) {
        self.selection = selection
    }

    init() {
        self.selection = nil
    }

    var body: some View {
        VStack {
            ...
        }
        .onChange(of: selection) { newValue in   <== ERROR
            ...
        }
    }
}

Я получаю следующую ошибку: Referencing instance method 'onChange(of:perform:)' on 'Optional' requires that 'Binding<T?>' conform to 'Equatable'.

Как это можно решить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
243
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Переключиться на использование оболочки

struct MyView<T : Hashable>: View {
    @Binding var selection: T?

    init(selection: Binding<T?>) {
        self._selection = selection
    }

    init() {
        //Dead end not recommended for use outside of Previews
        //Will cause undesirable behavior by mimicking having a source of truth.
        self._selection = .constant(nil)
    }

    var body: some View {
        VStack {
            Text("")
        }
        .onChange(of: selection) { newValue in   //<== ERROR
            //Do work here
        }
    }
}

https://developer.apple.com/documentation/swiftui/binding/constant(_:)

Вы также должны отметить, что Binding по определению двустороннее соединение.

Зачем Binding, если его изменения зайдут в тупик? Аналогичные результаты можно получить с...

struct MyView<T : Hashable>: View {
    let selection: T?

    var body: some View {
        VStack {
            Text("")
        }.onAppear(){
            //Do work here
        }
    }
}

private let selection: Binding<T?>? «эквивалентен» (но не совсем) использованию оболочки и последующему доступу к $selection.

Я никогда не вникал в причину, по которой SwiftUI требует обертки, а не только типы, но это связано с соответствием DynamicProperty, wrappedValue и projectedValue. View не будет знать, когда обновлять, если вы используете Binding<Type> против @Binding.

Нежелательное поведение с представлениями, которые предоставят пользователю UX, намекающий на то, что его действия влияют на что-то значимое, плюс есть другие ошибки, такие как дерганое поведение и неотзывчивый пользовательский интерфейс.

@lorem ipsum прав, много вопросов у людей, пытающихся передать значения с помощью Binding<T>... в этом нет необходимости, просто передайте значение через инициализацию или конструктор по умолчанию (если вы не реализовали ни одну инициализацию), эти представления все равно каждый раз разрушаются и реконструируются.

Allan Garcia 10.11.2022 18:55

Спасибо, это сработало. В полном коде selection нет тупика. Не могли бы вы объяснить, что вызвало мою ошибку и почему использование оболочки решает ее? Какое нежелательное поведение может произойти и что именно?

meaning-matters 10.11.2022 21:38

@meaning-matters Я добавил дополнительную информацию.

lorem ipsum 10.11.2022 21:56

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