目前 SwiftUI 不支持本机多行文本输入(希望这个功能很快能被添加!),因此我一直在尝试使用 Combine 框架来实现自适应多行 UITextVIew 的输入功能,但是效果并不稳定。
以下是我编写的 Text 视图代码:
struct MultilineTextView: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UITextView {
let view = UITextView()
view.isScrollEnabled = true
view.isEditable = true
view.isUserInteractionEnabled = true
view.backgroundColor = UIColor.white
view.textColor = UIColor.black
view.font = UIFont.systemFont(ofSize: 17)
view.delegate = context.coordinator
return view
}
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
}
func frame(numLines: CGFloat) -> some View {
let height = UIFont.systemFont(ofSize: 17).lineHeight * numLines
return self.frame(height: height)
}
func makeCoordinator() -> MultilineTextView.Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: MultilineTextView
init(_ parent: MultilineTextView) {
self.parent = parent
}
func textViewDidChange(_ textView: UITextView) {
parent.text = textView.text
}
}
}
我随后在SwiftUI视图中实现了它,如下所示:
MultilineTextView(text: title ? $currentItem.titleEnglish : $currentItem.pairArray[currentPair].english)//.frame(numLines: 4)
并将其绑定到状态变量:
@State var currentItem:Item
它有些可行。但是状态变量 currentItem:Item 包含一个字符串数组,我正在使用按钮循环它并基于输入到 MultilineTextView 中的内容更新字符串数组。这就是我遇到问题的地方,MultilineTextView 似乎只绑定到数组中的第一个字符串项,然后它就不会改变了。当我使用 swiftUI 的原生 TextField 视图时,这个功能运行正常,我可以循环访问字符串数组并通过在 TextField 中输入文本进行更新。
我认为在 MultilineTextView 结构体中必须缺失某些功能。欢迎任何指针。
更新:添加了模型结构。
struct Item: Identifiable, Codable {
let id = UUID()
var completed = false
var pairArray:[TextPair]
}
struct TextPair: Identifiable, Codable {
let id = UUID()
var textOne:String
var textTwo:String
}
编辑: 经过我进一步的调查,我发现了可能的问题。当UITextView的textViewDidChange被触发时,它确实会发送更新的文本,这些文本可以在控制台中看到。奇怪的是,updateUIView函数也会被触发,并使用更新之前绑定变量中的内容来更新UITextView的文本。结果是,当您键入内容时,UITextview就拒绝更改。奇怪的是,它对于数组中的第一个字符串有效,但是当项目更改后,它将不再起作用。
Item
是什么吗? - Asperi