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 模拟 CSS flex-wrap 行为