2

我有一个TextField用户可编辑的,但也可以通过对ViewModel.

然而,似乎有一些神秘的魔法决定了我何时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

4

2 回答 2

1

它甚至可以在 Playground 中使用。

要在 Playground 中查看结果视图,您需要告诉 Playground 显示它。

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)
        }
    }

因此所有更改都将直接可见。

左右,在真实环境中进行测试是必要的。

在此处输入图像描述

于 2020-02-28T06:44:08.550 回答
1

这是特定于 Playground 的行为,因为它似乎会在每次更新时重新创建视图(甚至来自视图模型),所以fetch只是没有收到。将此代码放入项目中并在实时预览或模拟器中进行测试 - 一切正常。

使用 Xcode 11.2 / iOS 13.2 测试。

于 2020-02-28T05:37:36.603 回答