有没有办法以声明的方式获取UITextField的文本更新?

时间:2019-11-20 01:51:24

标签: ios swift combine

我很困惑为什么下面的代码不起作用。


dateTextField.publisher(for: \.text)
    .sink(receiveCompletion: { completion  in
        print("completion", completion)
    }, receiveValue: { value in
        print("value", value ?? "")
    }).store(in: &subscriptions)


我刚收到一个空文本的第一个事件。我的猜测是因为UITextField的text属性不兼容KVO。但是,为什么订阅会收到第一个值?

3 个答案:

答案 0 :(得分:1)

您现在可以收听NotificationCenter更新

NotificationCenter.default.publisher(for: UITextField.textDidChangeNotification, object: yourTextField).map { ($0.object as! UITextField).text }

答案 1 :(得分:0)

目前尚不清楚您使用它的方式和位置(哪个运行时环境),但是它可以工作。经过Xcode 11.2 / Swift 5.1 / iOS 13.2的测试

这是SwiftUI中测试UITextField发布者的演示(只是将发布者附加到现有测试中,并且可以正常工作)。希望它能有所帮助。

import SwiftUI
import Combine
import UIKit

struct TextView: UIViewRepresentable {
    @Binding var text: String

    private let cancelable: AnyCancellable
    private let myTextView: UITextView

    init(text: Binding<String>) {
        self._text = text
        myTextView = UITextView()

        myTextView.isScrollEnabled = true
        myTextView.isEditable = true
        myTextView.isUserInteractionEnabled = true
        cancelable = myTextView.publisher(for: \.text)
            .sink { value in
                print("Get: \(value ?? "no value")")
            }
    }

    func makeUIView(context: Context) -> UITextView {
        self.myTextView.delegate = context.coordinator
        return self.myTextView
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator : NSObject, UITextViewDelegate {
        var parent: TextView

        init(_ uiTextView: TextView) {
            self.parent = uiTextView
        }

        func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
            return true
        }

        func textViewDidChange(_ textView: UITextView) {
            self.parent.text = textView.text
        }
    }
}

struct TestTextViewNewLine: View {
    @State var text = ""
    var body: some View {
        HStack {
            Text("Label:")
            TextView(text: $text)
                .background(RoundedRectangle(cornerRadius: 4).stroke())
                .frame(maxHeight: 32)
        }
    }
}

struct TestTextViewNewLine_Previews: PreviewProvider {
    static var previews: some View {
        TestTextViewNewLine()
    }
}

输出:

2019-11-21 21:59:10.436516+0200 Test[1122:35207] [Agent] Received display message
Get: 
Get: 
Get: H
Get: He
Get: Hel
Get: Hell
Get: Hello

答案 2 :(得分:0)

我也遇到过同样的问题,显然有一个明显的原因:我的控制器被释放了。因此,我建议同时检查订阅和拥有订阅的对象