是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
是否有一个好的方法来调整UITextView的大小以符合其内容?例如,我有一个包含一行文本的UITextView:
"Hello world"
然后我添加了另一行文本:
"Goodbye world"
在Cocoa Touch中是否有一个好的方法来获取矩形来保存文本视图中的所有行,这样我就可以相应地调整父视图?
另一个例子是,查看Calendar应用程序中用于事件的notes字段——注意单元格(以及它包含的UITextView)如何展开以保存notes字符串中的所有文本行。
当前回答
我会在页面底部发布正确的解决方案,以防有人勇敢(或绝望)读到这一点。
这里是那些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];
其他回答
迅速:
textView.sizeToFit()
我们可以用约束来做。
为UITextView设置高度约束。
2.为高度限制创建IBOutlet。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;
3.不要忘记为你的textview设置委托。
4.
-(void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
[UIView animateWithDuration:0.2 animations:^{
_txtheightconstraints.constant=newFrame.size.height;
}];
}
然后像这样更新你的约束:
这适用于iOS 6.1和iOS 7:
- (void)textViewDidChange:(UITextView *)textView
{
CGFloat fixedWidth = textView.frame.size.width;
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
CGRect newFrame = textView.frame;
newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
textView.frame = newFrame;
}
或在Swift(适用于Swift 4.1在iOS 11)
let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
如果你想要支持iOS 6.1,那么你还应该:
textview.scrollEnabled = NO;
The easiest way to ask a UITextView is just calling -sizeToFitit should work also with scrollingEnabled = YES, after that check for the height and add a height constraint on the text view with the same value. Pay attention that UITexView contains insets, this means that you can't ask the string object how much space it want to use, because this is just the bounding rect of the text. All the person that are experiencing wrong size using -sizeToFit it's probably due to the fact that the text view has not been layout yet to the interface size. This always happen when you use size classes and a UITableView, the first time cells are created in the - tableView:cellForRowAtIndexPath: the comes out with the size of the any-any configuration, if you compute you value just now the text view will have a different width than the expected and this will screw all sizes. To overcome this issue I've found useful to override the -layoutSubviews method of the cell to recalculate textview height.
迅速回答: 下面的代码计算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