简体   繁体   中英

Reset TextField value using Combine and Swiftui

I try to reset a TextField value when a certain condition is met (.count == 4) , but it does not work, what am I missing?

class ViewModel: ObservableObject {
    @Published var code = ""
    private var anyCancellable: AnyCancellable?
    init() {
        anyCancellable = $code.sink { (newVal) in
            if newVal.count == 4 {
                self.code = ""
            }
        }
    }
}
struct ContentView: View {
    
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        TextField("My code", text: $viewModel.code)
    }
}

This is a case where you don't need any Combine. Just use the normal didSet to observe changes to the property:

class ViewModel: ObservableObject {
    @Published var code = "" {
        didSet {
            if code.count == 4 {
                self.code = ""
            }
        }
    }
}

Adding .receive(on: DispatchQueue.main) seems to fix this issue, however, I am not entirly sure why it is needed.

On a side note, make sure you capture [weak self] in a sink block to avoid memory leaks:

anyCancellable = $code
            .receive(on: DispatchQueue.main) // <--
            .sink { [weak self] newVal in
                if newVal.count == 4 {
                    self?.code = ""
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM