是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
当前回答
这工作得很好,当我需要使文本在一个UITextView适合一个特定的区域:
// The text must already be added to the subview, or contentviewsize will be wrong. - (void) reduceFontToFit: (UITextView *)tv { UIFont *font = tv.font; double pointSize = font.pointSize; while (tv.contentSize.height > tv.frame.size.height && pointSize > 7.0) { pointSize -= 1.0; UIFont *newFont = [UIFont fontWithName:font.fontName size:pointSize]; tv.font = newFont; } if (pointSize != font.pointSize) NSLog(@"font down to %.1f from %.1f", pointSize, tv.font.pointSize); }
其他回答
我会在页面底部发布正确的解决方案,以防有人勇敢(或绝望)读到这一点。
这里是那些gitHub回购,谁不想读所有的文本:resizableTextView
这适用于iOs7(我相信它将适用于iOs8)和自动布局。你不需要魔法数字,禁用布局之类的东西。简洁优雅的解决方案。
我认为,所有约束相关的代码都应该去updateConstraints方法。让我们创建自己的ResizableTextView。
我们在这里遇到的第一个问题是在viewDidLoad方法之前不知道真实的内容大小。我们可以根据字体大小、换行等进行计算。但我们需要稳健的解决方案,所以我们会:
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
现在我们知道真实的contentSize,不管我们在哪里:在viewDidLoad之前还是之后。现在在textView上添加高度约束(通过storyboard或代码,无论如何)。我们用contentSize.height来调整这个值:
[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = contentSize.height;
*stop = YES;
}
}];
最后要做的事情是告诉超类updateConstraints。
[super updateConstraints];
现在我们的类看起来是这样的:
ResizableTextView.m
- (void) updateConstraints {
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = contentSize.height;
*stop = YES;
}
}];
[super updateConstraints];
}
又漂亮又干净,对吧?你不需要在控制器中处理这些代码!
但是等等! 没有动画!
你可以很容易地动画变化,使textView伸展顺利。这里有一个例子:
[self.view layoutIfNeeded];
// do your own text change here.
self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
[self.infoTextView setNeedsUpdateConstraints];
[self.infoTextView updateConstraintsIfNeeded];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
[self.view layoutIfNeeded];
} completion:nil];
结合迈克·麦克马斯特的回答,你可能会想这样做:
[myTextView setDelegate: self];
...
- (void)textViewDidChange:(UITextView *)textView {
if (myTextView == textView) {
// it changed. Do resizing here.
}
}
唯一可以工作的代码是使用'SizeToFit'的代码,如上面的jhibberd answer,但实际上它不会拾取,除非你在ViewDidAppear中调用它或将其连接到UITextView text changed event。
你试过[textView sizeThatFits:textView. txt]吗?范围)?
编辑:sizeThatFits返回大小,但并不实际调整组件的大小。我不确定如果这是你想要的,或者如果[textView sizeToFit]是更多的你要寻找的。无论哪种情况,我不知道它是否完全适合你想要的内容,但这是第一件要尝试的事情。
这对于Swift 5来说很好,以防你想要适合你的TextView,一旦用户在运行中写文本。
只需实现UITextViewDelegate:
func textViewDidChange(_ textView: UITextView) {
let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: newSize.width, height: newSize.height)
}