SwiftUI Запуск вызова метода при изменении свойства Bindable - PullRequest
0 голосов
/ 03 ноября 2019

Я изо всех сил пытаюсь понять, как запустить метод при изменении объекта Bindable. Вот код, который у меня есть: enter image description here

Однако по какой-то причине метод fetchFoods никогда не вызывается в результате изменения searchText, и я не могу понять,почему.

1 Ответ

0 голосов
/ 04 ноября 2019

@ Хариш @ Аспери, вы, ребята, путаете. Есть конкретная причина, по которой метод @ Harish не вызывается. Давайте создадим простой пример:

struct ContentView: View {
    @State private var text = "" {
        didSet {
            print("Triggered!")
        }
    }

    var body: some View {
        VStack {
            TextField("Type something...", text: $text)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Если вы скопируете вставить и запустите этот минимальный жизнеспособный пример, вы увидите, что строка «Triggered!»никогда не будет напечатан. И это потому, что то, что вы изменяете через $ binding , - это не свойство text, а значение , связанное с привязкой , доступное через знак $. Это две совершенно разные вещи. Это действительно важно понять.

Итак, почему работает пример @ Asperi? (Я немного упростил его, чтобы создать еще один минимально жизнеспособный пример):

struct ContentView: View {
    @State private var isOn = false {
        didSet {
            print("Triggered!")
        }
    }
    var body: some View {
        Button(
            action: { self.isOn.toggle() },
            label: { Text(self.isOn ? "Hide" : "Show") }
        )
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

На этот раз, если вы скопируете и вставите этот код, вы увидите, что «Сработало!»будет напечатан. И это хорошо, потому что, нажимая на кнопку, вы меняете точно self.isOn. На этот раз вы не используете какой-либо знак $ для доступа к обернутому значению привязки.

Примеры, приведенные выше, похоже, используют один и тот же подход, но на самом деле они действительно разные. И опять же, очень важно понимать эту разницу. Итак, как вы можете получить то, что вы хотите (например, «запустить метод при изменении объекта Bindable»)? Вы должны полагаться на ViewModel и @Published упаковщик свойств:

class ViewModel: ObservableObject {
    @Published var text = "" {
        didSet {
            print("Triggered!")
        }
    }
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        VStack {
            TextField("Type something...", text: $viewModel.text)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

, предназначенные именно для этого:

Упаковка свойств комбината «Опубликовано» похожа по духу[на другие оболочки свойств], позволяя клиентам подписываться на свойства @Published (через $ projection) для получения обновлений при изменении значения .

С https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...