是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
当前回答
对我来说最简单的解决方案是在Storyboard的textView上放一个高度约束,然后将textView和高度约束连接到代码:
@IBOutlet var myAwesomeTextView: UITextView!
@IBOutlet var myAwesomeTextViewHeight: NSLayoutConstraint!
然后在设置文本和段落样式后,在viewDidAppear中添加这个:
self.myAwesomeTextViewHeight.constant = self.myAwesomeTextView.contentSize.height
一些注意事项:
与其他解决方案相比,必须将isScrollEnabled设置为true才能使其工作。 在我的例子中,我在代码中设置自定义属性的字体,因此我必须在viewDidAppear中设置高度(在此之前它不会正常工作)。如果你没有在代码中更改任何文本属性,你应该能够在viewDidLoad或设置文本后的任何地方设置高度。
其他回答
根据我有限的经验,
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode
不尊重换行符,所以你最终可以得到比实际需要的更短的CGSize。
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
看起来很尊重换行符。
同样,文本也不是在UITextView顶部渲染的。在我的代码中,我将UITextView的新高度设置为比sizeOfFont方法返回的高度大24个像素。
以下是步骤
解决方案适用于所有版本的iOS。Swift 3.0及以上版本。
添加你的UITextView到View。我用代码添加它,你可以通过界面生成器添加。 添加约束。我在代码中添加约束,你也可以在接口生成器中这样做。 使用UITextViewDelegate方法func textViewDidChange(_ textView: UITextView)来调整textView的大小
代码:
//1. Add your UITextView in ViewDidLoad let textView = UITextView() textView.frame = CGRect(x: 0, y: 0, width: 200, height: 100) textView.backgroundColor = .lightGray textView.text = "Here is some default text." //2. Add constraints textView.translatesAutoresizingMaskIntoConstraints = false [ textView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), textView.leadingAnchor.constraint(equalTo: view.leadingAnchor), textView.trailingAnchor.constraint(equalTo: view.trailingAnchor), textView.heightAnchor.constraint(equalToConstant: 50), textView.widthAnchor.constraint(equalToConstant: 30) ].forEach{ $0.isActive = true } textView.font = UIFont.preferredFont(forTextStyle: .headline) textView.delegate = self textView.isScrollEnabled = false textViewDidChange(textView) //3. Implement the delegate method. func textViewDidChange(_ textView: UITextView) { let size = CGSize(width: view.frame.width, height: .infinity) let estimatedSize = textView.sizeThatFits(size) textView.constraints.forEach { (constraint) in if constraint.firstAttribute == .height { print("Height: ", estimatedSize.height) constraint.constant = estimatedSize.height } } }
这在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+上的“额外行”问题。
具备以下条件就足够了:
只需要记住为你的UITextView设置滚动启用为NO:
正确设置自动布局约束。
你甚至可以使用UITableViewAutomaticDimension。
希望这能有所帮助:
- (void)textViewDidChange:(UITextView *)textView {
CGSize textSize = textview.contentSize;
if (textSize != textView.frame.size)
textView.frame.size = textSize;
}