如何根据文本长度使UITextView高度动态变化?

112

从这张图片中可以看到,UITextView的高度会根据文本长度改变,我希望它能够根据文本长度自动调整高度。

*我看到了其他的问题,但那里的解决方案对我没有用。

example


可能是如何根据UITextView的内容设置大小?的重复问题。 - Samuel Noyes
我使用nextGrowingTextView https://github.com/muukii/NextGrowingTextView 我甚至在Objective c中编写了一个实现 https://github.com/mcmatan/NextGrowingInternalTextViewObjectiveC - MCMatan
CSGrowingTextView也是解决这个问题的另一种选择:https://github.com/cloverstudio/CSGrowingTextView - Josip B.
请确保将拥抱和压缩阻力优先级设置为较低。 - Ethan SK
这些天它是完全自动化的 - 不要忘记禁用滚动。显然,您需要在视图周围设置正确的约束(与任何视图一样)。 - Fattie
不,这不是因为你太胖了。如果你使用本地字体,那肯定没问题,但一旦你导入另一种字体,问题就来了。 - Async-
23个回答

181

这对我来说起作用了,其他所有解决方案都没有。

func adjustUITextViewHeight(arg : UITextView) {
    arg.translatesAutoresizingMaskIntoConstraints = true
    arg.sizeToFit()
    arg.scrollEnabled = false
}

在 Swift 4 中,arg.scrollEnabled = false 的语法已更改为 arg.isScrollEnabled = false


1
请另外提问并提供完整的代码和故事板细节。 - DeyaEldeen
1
请在设置 .text 后设置这些属性 ;)。谢谢! - Lahiru Pinto
2
对于我的情况,只需要使用arg.sizeToFit()就足够了。arg.translatesAutoresizingMaskIntoConstraints会移除我的约束。 - Niib Fouda
1
谢谢@NiibFouda,你救了我的一天,只有arg.sizeToFit()就足够了。 - Walid Sassi
@WalidSassi 你好,朋友,欢迎。 - Niib Fouda
显示剩余2条评论

87
在Storyboard/Interface Builder中,只需在属性检查器中禁用滚动即可。
在代码中,textField.scrollEnabled = false应该就可以了。

3
我简直不敢相信这是如此简单。我认为这应该是被接受的答案。 - אורי orihpt
1
这个为什么能够解决问题的解释在这里:https://dev59.com/8mQn5IYBdhLWcg3wZGV4#65861960 - fumoboy007

52

我所需要做的是:

  1. 将textView的约束条件设置为上方、左侧和右侧
  2. 在Storyboard中禁用滚动

这样可以使自动布局根据其内容动态调整textView的大小。


3
整洁干净!谢谢 +1 - Yogesh Patel
1
在您编辑文本时,这是行不通的。 - Raja Saad

29

试一下这个:

CGRect frame = self.textView.frame;
frame.size.height = self.textView.contentSize.height;
self.textView.frame = frame;

编辑-这是Swift代码:

var frame = self.textView.frame
frame.size.height = self.textView.contentSize.height
self.textView.frame = frame

好的,谢谢。我也会尝试这个方法,并告诉您结果。 - DeyaEldeen

21

Swift 4

将其添加到您的类中

UITextViewDelegate

func textViewDidChange(_ textView: UITextView) {
      let fixedWidth = textView.frame.size.width
      textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
      var newFrame = textView.frame
      newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
      textView.frame = newFrame
}

它根据我的需求很好地工作。但是除了第一行之外,TextView键盘在第二次打开时不再起作用。有人能帮我吗? - Shangari C
2
textView.translatesAutoresizingMaskIntoConstraints = true 也是必需的。 - Ryan
当文本视图放弃第一响应者时,只需调用sizeToFit()。 - K. Mitra

15

在DeyaEldeen的回答之后。
对于我的情况,我通过添加
自动增加了文本视图的高度。

Swift 3

textView.translatesAutoresizingMaskIntoConstraints = false textView.isScrollEnabled = false


在我的情况下,使用textView.scrollEnabled = false;,它起作用了。 - Jonathan García
这对我的情况也适用。 - RainCast

10

Swift 5,使用扩展:

extension UITextView {
    func adjustUITextViewHeight() {
        self.translatesAutoresizingMaskIntoConstraints = true
        self.sizeToFit()
        self.isScrollEnabled = false
    }
}

使用案例:

textView.adjustUITextViewHeight()

不用担心 storyboard 中 textView 的高度(一开始只需使用一个常量)


9

只需连接您的textView的高度约束即可。

@IBOutlet var textView: UITextView!
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!

并使用以下代码
textViewHeightConstraint.constant = self.textView.contentSize.height

类型 'UITextField' 的值没有成员 'contentSize'。 - Ananta Prasad
@AnantaPrasad,这是UITextView而不是UItextField,请检查上面的连接。 - Rishabh Shukla

9
如果您的textView允许根据内容增高,则
textView.isScrollEnabled = false

应该可以与自动布局一起正常工作。

如果您希望保持 textView 的可滚动性,则需要添加一个可选的高度约束,

internal lazy var textViewHeightConstraint: NSLayoutConstraint = {
  let constraint = self.textView.heightAnchor.constraint(equalToConstant: 0)
  constraint.priority = .defaultHigh
  return constraint
}()

public override func layoutSubviews() {
  super.layoutSubviews()

  // Assuming there is width constraint setup on the textView.
  let targetSize = CGSize(width: textView.frame.width, height: CGFloat(MAXFLOAT))
  textViewHeightConstraint.constant = textView.sizeThatFits(targetSize).height
}

重写layoutSubviews()的原因是确保textView在水平方向上正确布局,以便我们可以依赖宽度来计算高度。
由于高度约束设置为较低的优先级,如果垂直空间不足,则textView的实际高度将小于contentSize。并且textView将可滚动。

9

我添加了这两行代码,对我很有效。

在Swift 5+中有效。

func adjustUITextViewHeight(textView : UITextView)
{
     textView.translatesAutoresizingMaskIntoConstraints = true
     textView.isScrollEnabled = false
     textView.sizeToFit()
}

1
简单,不需要使用库 - Lena Bru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接