首页 > 解决方案 > 为什么 UIViewRepresentables Coordinator 中的绑定具有恒定的读取值

问题描述

我一直在编写 UIViewRepresentable 并注意到一些关于我传递到视图中的绑定的古玩效果。当我通过保存的 UIViewRepresentable 读取协调器中的绑定值时,该值始终是初始化它的值。但是,尝试更新相同的绑定会触发周围 UI 的更新。

UI 未正确更新

这是代码产生这种行为:

struct NativeTextView: UIViewRepresentable {
    @Binding var text: String
    func makeUIView(context: Context) -> UITextField {
        let view = UITextField()
        view.borderStyle = .roundedRect
        view.addTarget(
            context.coordinator,
            action: #selector(Coordinator.updateText(sender:)),
            for: .editingChanged
        )
        return view
    }
    func updateUIView(_ uiView: UITextField, context: Context) {
        context.coordinator.updateUI(uiView)
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(_text)
    }
    class Coordinator: NSObject {
        @Binding var text: String
        init(_ text: Binding<String>){
            _text = text
        }
        @objc func updateText(sender: UITextField){
            text=sender.text!
        }
        func updateUI(_ uiView: UITextField) {
            uiView.text = text
        }
    }
}

如果我将鼠标悬停给我的 updateUI 方法一个 NativeTextView 参数,并通过参数使用它的 .text 字段,我会读取正确的值并且 UI 可以正常工作:

用户界面正常工作

struct NativeTextView: UIViewRepresentable {
    @Binding var text: String
    func makeUIView(context: Context) -> UITextField {
        let view = UITextField()
        view.borderStyle = .roundedRect
        view.addTarget(
            context.coordinator,
            action: #selector(Coordinator.updateText(sender:)),
            for: .editingChanged
        )
        return view
    }
    func updateUIView(_ uiView: UITextField, context: Context) {
        context.coordinator.updateUI(uiView, view: self)
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    class Coordinator: NSObject {
        var myView: NativeTextView
        init(_ view: NativeTextView){
            self.myView=view
        }
        @objc func updateText(sender: UITextField){
            myView.text=sender.text!
        }
        func updateUI(_ uiView: UITextField, view: NativeTextView) {
            uiView.text = view.text
        }
    }
}

似乎绑定保留了写入外部 @State 变量的能力,但无法正确访问当前状态值。我猜这与 SwiftUI 注意到 @State 更新时重新创建 NativeTextView 视图有关,但我无法找到任何可以解释这种行为的文档。有谁知道为什么会这样?

PS:为了完整起见,这是我的 ContentViews 正文:

ZStack {
    Color.red
    VStack {
        Text(test)
            .padding()
            .onTapGesture() {
                test = "Bla"
            }
            NativeTextView(text: $test)
        }
}

标签: swiftswiftuiuiviewrepresentable

解决方案


推荐阅读