UITextView 的 SwiftUI Wrapper 未更新 ObservedObject

Posted

技术标签:

【中文标题】UITextView 的 SwiftUI Wrapper 未更新 ObservedObject【英文标题】:SwiftUI Wrapper for UITextView not updating ObservedObject 【发布时间】:2019-10-23 20:41:42 【问题描述】:

我希望我错了,但我一直无法找到与可编辑的 SwiftUI 等效的 界面文本视图。因此,我使用 UIViewRepresentable 构建了一个。填充 SwiftUI 文本 并且我自己对 ObservableObject 的看法是有效的——但在我的看法中所做的更新是 没有传播到 ObservableObject。我一定错过了一些重要的东西 绑定概念。任何指导将不胜感激。

import SwiftUI
import Combine

struct ContentView: View 

    @ObservedObject var myOText: MyOText

    var body: some View 
        ScrollView 
            VStack 
                Text("This is a bound Text View")
                    .padding(.top, 10)
                    .font(.headline)

                Text(myOText.inTheCourse)
                    .lineLimit(3)
                    .padding()

                Text("This is a multi-line UITextView wrapper:")
                    .font(.headline)

                MultilineTextView(myOText: myOText)
                    .frame(height: 100)
                    .padding()

                Spacer()
            
        
    


struct MultilineTextView: UIViewRepresentable 

    @ObservedObject var myOText: MyOText

    func makeUIView(context: Context) -> UITextView 
        let view = UITextView()
        view.isScrollEnabled = true
        view.isEditable = true
        view.isUserInteractionEnabled = true
        view.textAlignment = .center
        view.font = UIFont(name: "Times New Roman", size: 20)
        return view
    

    func updateUIView(_ uiView: UITextView, context: Context) 
        uiView.text = myOText.inTheCourse
    


class MyOText: ObservableObject 
    @Published var inTheCourse: String = "When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them ..."


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView(myOText: MyOText())
    

Xcode 版本 11.2 beta 2 (11B44),ios 13。

【问题讨论】:

inTheCourse 的更改是否会传播到您的 UIKit 视图?我问是因为在我的情况下,@ObservedObject 的更改不会触发updateUIViewController(在我的情况下使用UIViewControllerRepresentable)。 我没有那样使用它。我将 myOText 保存到 Core Data,然后当然从 Core Data 加载。但是,我使用连接到 ObservedObject 的 myOText、TextField 和 Text View 进行了简化测试,并且在 TextField 中键入更新了 Text View 但没有更新 myOText - 正如您所建议的那样。必须以某种方式指示协调员这样做。也许杰夫或其他人可以发表评论。 【参考方案1】:

你的多行文本视图需要一个协调器来观察来自 UITextView 的文本更新

struct MultilineTextView: UIViewRepresentable 
    @ObservedObject var myOText: MyOText

    func makeUIView(context: Context) -> UITextView 
        let view = UITextView()
        view.isScrollEnabled = true
        view.isEditable = true
        view.isUserInteractionEnabled = true
        view.textAlignment = .center
        view.font = UIFont(name: "Times New Roman", size: 20)
        view.delegate = context.coordinator
        return view
    

    func updateUIView(_ uiView: UITextView, context: Context) 
        uiView.text = myOText.inTheCourse
    

    func makeCoordinator() -> MultilineTextView.Coordinator 
        Coordinator(self)
    

    class Coordinator: NSObject, UITextViewDelegate 
        var control: MultilineTextView

        init(_ control: MultilineTextView) 
            self.control = control
        

        func textViewDidChange(_ textView: UITextView) 
            control.myOText.inTheCourse = textView.text
        
    

【讨论】:

太棒了。像冠军一样工作。 这很奇怪,但是以这种方式包装的 UITextView 会通过将光标跳转到整个文本的末尾来响应返回。同样,当在空行上按退格键时,它会跳转到文本的末尾。 @jeff 我怎样才能显示默认文本(灰色),一旦用户输入他的文本,然后常规的黑色文本将替换它,反之亦然,如果他们删除文本? @Munhitsu 我遇到了同样的光标跳跃问题,并在我的 updateUIView 中修复了它,仅在 UITextView 的文本发生变化时更新它。

以上是关于UITextView 的 SwiftUI Wrapper 未更新 ObservedObject的主要内容,如果未能解决你的问题,请参考以下文章

在 SwiftUI 中为 UITextView 设置初始视图偏移量

UITextView 在 SwiftUI 中可表示不尊重 ScrollView 中的宽度界限

SwiftUI UITextView 协调器不起作用

使用 SwiftUI 模拟 CSS flex-wrap 行为

SwiftUI Word Wrap 用于多行文本 Word 断字问题

UITextView 根据内容动态改变高度?