是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:

"Hello world"

然后我添加了另一行文本:

"Goodbye world"

在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?

另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。


当前回答

看起来这个家伙为NSTextView找到了答案,他的答案也适用于iOS。事实证明,intrinsicContentSize并不与布局管理器同步。如果一个布局发生在intrinsicContentSize之后,你可能会有一个差异。

他有一个简单的解决办法。

NSOutlineView中的NSTextView与IntrinsicContentSize设置错误的高度

其他回答

结合迈克·麦克马斯特的回答,你可能会想这样做:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}

我回顾了所有的答案,所有都保持固定的宽度和调整只有高度。如果你想调整宽度,你可以很容易地使用这个方法:

当配置文本视图时,将滚动设置为禁用

textView.isScrollEnabled = false

然后在委托方法func textViewDidChange(_ textView: UITextView)添加以下代码:

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}

输出:

这在ios7或更高版本上不再适用

实际上有一个非常简单的方法来调整UITextView的大小,使其达到内容的正确高度。它可以使用uitextviewcontentsize来完成。

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

需要注意的一件事是,只有在使用addSubview将UITextView添加到视图之后,正确的contentSize才可用。在此之前,它等于frame。size

如果开启自动布局,这将不起作用。对于自动布局,一般的方法是使用sizeThatFits方法并在高度约束上更新常量值。

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;

hightconstraint是一个布局约束,通常通过IBOutlet将属性链接到故事板中创建的高度约束来设置。


再加上这个惊人的答案,2014年,如果你:

[self.textView sizeToFit];

只有iPhone6+有不同的表现:

只有6+(不是5s或6),它确实添加了“一个更多的空白行”到UITextView。“RL解决方案”完美地解决了这个问题:

CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

它修复了6+上的“额外行”问题。

从iOS 8开始,可以使用UITableView的自动布局功能来自动调整UITextView的大小,而不需要任何自定义代码。我在github上放了一个项目,演示了这一点,但关键是:

UITextView必须禁用滚动,这可以通过编程或通过接口构建器来实现。如果启用滚动,它将不会调整大小,因为滚动可以让您查看较大的内容。 在UITableViewController的viewDidLoad中,你必须为estimatedRowHeight设置一个值,然后将rowHeight设置为UITableViewAutomaticDimension。


- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}

项目部署目标必须是iOS 8或更高版本。

迅速回答: 下面的代码计算textView的高度。

                let maximumLabelSize = CGSize(width: Double(textView.frame.size.width-100.0), height: DBL_MAX)
                let options = NSStringDrawingOptions.TruncatesLastVisibleLine | NSStringDrawingOptions.UsesLineFragmentOrigin
                let attribute = [NSFontAttributeName: textView.font!]
                let str = NSString(string: message)
                let labelBounds = str.boundingRectWithSize(maximumLabelSize,
                    options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                    attributes: attribute,
                    context: nil)
                let myTextHeight = CGFloat(ceilf(Float(labelBounds.height)))

现在你可以设置你的textView的高度为myTextHeight