@ Хариш @ Аспери, вы, ребята, путаете. Есть конкретная причина, по которой метод @ 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