【发布时间】:2021-03-10 04:57:36
【问题描述】:
我在 SwiftUI 应用程序中使用UITextView,以便根据以下答案获取可编辑的多行文本字段列表:How do I create a multiline TextField in SwiftUI?
我在 SwiftUI 中这样使用组件:
@State private var textHeight: CGFloat = 0
...
GrowingField(text: $subtask.text ?? "", height: $textHeight, changed:{
print("Save...")
})
.frame(height: textHeight)
GrowingField 的定义如下:
struct GrowingField: UIViewRepresentable {
@Binding var text: String
@Binding var height: CGFloat
var changed:(() -> Void)?
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
textView.isScrollEnabled = false
textView.backgroundColor = .orange //For debugging
//Set the font size and style...
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
if uiView.text != self.text{
uiView.text = self.text
}
recalculateHeight(textView: uiView, height: $height)
}
func recalculateHeight(textView: UITextView, height: Binding<CGFloat>) {
let newSize = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
if height.wrappedValue != newSize.height {
DispatchQueue.main.async {
height.wrappedValue = newSize.height
}
}
}
//Coordinator and UITextView delegates...
}
我遇到的问题是sizeThatFits 首先计算正确的高度,然后用不正确的高度替换它。如果我 print newSize 在 recalculateHeight() 内,当我的视图加载时会这样:
(63.0, 34.333333333333336) <!-- Right
(3.0, 143.33333333333334) <!-- Wrong
(3.0, 143.33333333333334) <!-- Wrong
我不知道错误的尺寸是从哪里来的,我也不知道为什么要替换正确的尺寸。这是高度太大时的样子:
如果我对其进行更改,recalculateHeight() 方法会再次通过 textViewDidChange() 调用,并且它会自行处理:
这真的很hacky,但如果我在makeUIView() 中设置一个计时器,它也会自行修复:
//Eww, gross...
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
recalculateHeight(view: textView, height: $height)
}
知道如何确定不正确的sizeThatFits 值来自何处以及如何修复它吗?
【问题讨论】:
标签: swiftui uitextview uitextviewdelegate uiviewrepresentable