SwiftUI当前不支持多行文本输入(希望很快会添加此功能!),因此我一直在尝试使用Combine框架从UIKit实现不支持多行输入的UITextView,但是我一直在结果不一。
这是我创建的用于创建“文本”视图的代码:
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
这类作品。但是,状态var 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函数随后也被触发,并且它通过textViewDidChange发送更新之前,使用绑定变量中的内容更新了UITextView的文本。结果是,当您键入UITextview时,它只是拒绝更改。奇怪的是,它适用于数组中的第一个String,但是更改项目后将不再起作用。
答案 0 :(得分:1)
SwiftUI似乎为每个绑定创建UIViewRepresentable
的两个变体,但是在状态(即title
被切换时…………)可能由于缺陷而没有切换,值得向苹果公司提交。
我找到了解决方法(已通过Xcode 11.2 / iOS 13.2测试),而是使用如下所示的显式不同视图
if title {
MultilineTextView(text: $currentItem.titleEnglish)
} else {
MultilineTextView(text: $currentItem.pairArray[currentPair].textOne)
}
答案 1 :(得分:0)
所以最后我弄清楚了这个问题,之所以没有更新,是因为我传入了一个带有两个状态变量的字符串。您可以在下一行中看到,currentItem是一个状态变量,而currentPair是另一个状态变量,它提供索引号来定位字符串。后者没有被更新,因为它也没有通过绑定传递到多行文本视图中。
MultilineTextView(text: title ? $currentItem.titleEnglish : $currentItem.pairArray[currentPair].english)
我最初认为传递一个是可以的,父视图可以处理另一个,但是事实并非如此。我通过制作两个绑定变量解决了我的问题,因此我可以动态地找到想要的字符串。现在听起来很愚蠢,但当时看不到。