可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小
Posted
技术标签:
【中文标题】可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小【英文标题】:Resizable UITextView Has sizeThatFits That Gives Wrong Size in UIViewRepresentable 【发布时间】: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
值来自何处以及如何修复它吗?
【问题讨论】:
【参考方案1】:我花了很长时间才找到解决方案。事实证明UITextView
大小调整逻辑很好。这是一个父动画,它展示了我的视图,它导致updateUIView
再次以过渡中的UITextView
大小值触发。
通过在包含我所有文本字段的父 VStack
上设置 .animation(.none)
,它停止了动画的传播,现在它可以工作了。 ?
【讨论】:
以上是关于可调整大小的 UITextView 的 sizeThatFits 在 UIViewRepresentable 中给出了错误的大小的主要内容,如果未能解决你的问题,请参考以下文章