【问题标题】:Resizable UITextView Has sizeThatFits That Gives Wrong Size in UIViewRepresentable可调整大小的 UITextView 的 sizeThatFits 在 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 newSizerecalculateHeight() 内,当我的视图加载时会这样:

(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


    【解决方案1】:

    我花了很长时间才找到解决方案。事实证明UITextView 大小调整逻辑很好。这是一个父动画,它展示了我的视图,它导致updateUIView 再次以过渡中的UITextView 大小值触发。

    通过在包含我所有文本字段的父 VStack 上设置 .animation(.none),它停止了动画的传播,现在它可以工作了。 ?

    【讨论】:

      猜你喜欢
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-10
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多