Почему привязка не работает между View и ViewModel в Playgrounds? - PullRequest
2 голосов
/ 28 февраля 2020

У меня есть TextField, который редактируется пользователем, но может также обновляться изменениями в ViewModel.

Похоже, что некоторые магические маги c определяют, когда мои TextField обновления сам по себе, однако.

Вот игровая площадка:

import Combine
import SwiftUI

class ViewModel: ObservableObject {

    @Published var text: String = "0"

    private var cancellables: [AnyCancellable] = []

    init() {
        // output what the value of `text` is, whenever it changes
        let c = $text.print().sink { _ in }
        cancellables.append(c)
    }

    func fetch() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.text += "3"
        }
    }

    deinit { print("deinit") }
}

struct V: View {

    @ObservedObject var viewModel = ViewModel()

    init() {
        viewModel.text += "1"
    }

    var body: some View {
        TextField("TextField", text: $viewModel.text)
            .onAppear { self.viewModel.text += "2" }
            .onAppear { self.viewModel.fetch() }
    }
}

var v: V? = V()

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    v = nil
}

Я могу видеть из print() в ViewModel.init(), что ViewModel.text обновляется, как и ожидалось. Конечное значение: 0123.

Что я не понимаю: почему значение TextField перестает обновляться, когда оно достигает 012?

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Работает даже на игровой площадке.

Чтобы увидеть получившийся вид на игровой площадке, нужно указать игровой площадке показать его.

import PlaygroundSupport

и

PlaygroundPage.current.setLiveView(v)

сделает свое дело. Наконец, я также изменяю

var body: some View {
        VStack {
            TextField("TextField", text: $viewModel.text).font(.largeTitle)
            .onAppear {
                self.viewModel.text += "2"
                self.viewModel.fetch()
        }
            Text(viewModel.text).font(.largeTitle).frame(width: 200)
        }
    }

, чтобы все изменения были видны напрямую.

Так или иначе, тестирование в реальной среде необходимо.

enter image description here

1 голос
/ 28 февраля 2020

Это поведение, определяемое Playground c, потому что, похоже, оно воссоздает представление при каждом обновлении (даже из модели представления), поэтому fetch просто не получено. Поместите этот код в проект и протестируйте в Live Preview или Simulator - все работает хорошо.

Протестировано с Xcode 11.2 / iOS 13.2.

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