如何解决可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小
我在 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()
再次被调用,并且它会自行处理:
这真的很棘手,但如果我在 makeUIView()
中放置一个计时器,它也会自行修复:
//Eww,gross...
Timer.scheduledTimer(withTimeInterval: 1.0,repeats: false) { _ in
recalculateHeight(view: textView,height: $height)
}
知道如何确定不正确的 sizeThatFits
值的来源以及如何修复它吗?
解决方法
我花了很长时间才找到解决方案。事实证明 details: "Not a valid origin for the client: http://localhost has not been whitelisted for client ID xxxx.apps.googleusercontent.com . Please go to https://console.developers.google.com/ and whitelist this origin for your project's client ID." error: "idpiframe_initialization_failed"
大小调整逻辑很好。这是一个显示我的视图的父动画,它导致 UITextView
再次以过渡中的 updateUIView
大小值触发。
通过在包含我所有文本字段的父 UITextView
上设置 .animation(.none)
,它停止了动画的传播,现在它可以工作了。 ?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。