如何调整UITextView的内容?
有一个好的方法来调整UITextView的大小以符合其内容? 说例如我有一个UITextView包含一行文本: 
 "Hello world" 
然后我添加另一行文字:
 "Goodbye world" 
 在Cocoa Touch中是否有一个很好的方法来获得将保存文本视图中所有行的rect ,以便我可以相应地调整父视图? 
 作为另一个例子,查看日历应用程序中事件的注释字段 – 注意单元格(以及它所包含的UITextView )如何扩展,以保存注释string中的所有文本行。 
这适用于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中
 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 
如果你想支持iOS 6.1,那么你还应该:
 textview.scrollEnabled = NO; 
这不再适用于iOS 7或以上
 实际上有一个非常简单的方法来调整UITextView的正确高度的内容。 它可以使用UITextView contentSize来完成。 
 CGRect frame = _textView.frame; frame.size.height = _textView.contentSize.height; _textView.frame = frame; 
 有一点需要注意的是正确的contentSize只有在 UITextView通过addSubview添加到视图后才可用。 在此之前,它等于frame.size 
 如果自动布局为ON,这将不起作用。 对于自动布局,一般的方法是使用sizeThatFits方法并在高度约束上更新constant量值。 
 CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size]; heightConstraint.constant = sizeThatShouldFitTheContent.height; 
  heightConstraint是一个布局约束,您通常通过将属性链接到在故事板中创build的高度约束来通过IBOutlet进行设置。 
只是为了增加这个惊人的答案,2014年,如果你:
 [self.textView sizeToFit]; 
只有在iPhone6 +的行为有所不同:

只有6+(不是5或6),它会在UITextView中增加一个“空白行”。 “RL解决scheme”完美地解决了这个问题:
 CGRect _f = self.mainPostText.frame; _f.size.height = self.mainPostText.contentSize.height; self.mainPostText.frame = _f; 
它修复了6+的“额外线路”问题。
 为了在UITableViewCell创build一个dynamicresize的UITextView ,我在iOS 8 SDK中发现了Xcode 6中的以下组合: 
-  将UITextView添加到UITableViewCell并将其限制在边上
-  将UITextView的scrollEnabled属性设置为NO。 启用滚动function后,UITextView的框架与其内容大小无关,但禁用滚动function时,两者之间存在关系。
- 
如果您的表格使用的是原始的默认行高度44,那么它将自动计算行高度,但是如果将默认行高度更改为其他值,则可能需要手动打开 viewDidLoad中行高的自动计算:tableView.estimatedRowHeight = 150; tableView.rowHeight = UITableViewAutomaticDimension;
 对于只读dynamic调整UITextView的大小,就是这样。 如果您允许用户编辑UITextView的文本,则还需要: 
- 
实现 UITextViewDelegate协议的textViewDidChange:方法,并在每次编辑文本时告诉tableView自己重绘:- (void)textViewDidChange:(UITextView *)textView; { [tableView beginUpdates]; [tableView endUpdates]; }
- 
不要忘记设置 UITextView委托的地方,在Storyboard或在tableView:cellForRowAtIndexPath:
Swift:
 textView.sizeToFit() 
在我(有限)的经历中,
 - (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode 
 不尊重换行符,所以最终CGSize比实际需要的CGSize更短。 
 - (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size 
似乎尊重换行符。
 另外,文本实际上并不在UITextView的顶部。 在我的代码中,我将UITextView的新高度设置为比sizeOfFont方法返回的高度大24个像素。 
 在iOS6中,您可以在设置文本后立即检查UITextView的contentSize属性。 在iOS7中,这将不再起作用。 如果您想为iOS7恢复此行为,请将以下代码放在UITextView的子类中。 
 - (void)setText:(NSString *)text { [super setText:text]; if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) { CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer]; UIEdgeInsets inset = self.textContainerInset; self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size; } } 
我会在页面的底部张贴正确的解决scheme,以防万一有人勇敢(或绝望地)读到这一点。
这里是gitHub回购为那些谁不想读取所有文本: resizableTextView
这与iOs7(我相信它会与iOs8一起工作)和自动布局一起工作。 你不需要神奇的数字,禁用布局和类似的东西。 简洁优雅的解决scheme。
 我认为所有与约束有关的代码都应该去updateConstraints方法。 所以,我们来创build我们自己的ResizableTextView 。 
 我们遇到的第一个问题是,在viewDidLoad方法之前不知道真正的内容大小。 我们可以采取漫长的马路,并根据字体大小,换行符等进行计算。但是我们需要强大的解决scheme,所以我们要做: 
 CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)]; 
 所以现在我们知道真正的contentSize,无论我们在哪里:在viewDidLoad之前或之后。 现在,添加高度约束textView(通过故事板或代码,无论如何)。 我们将使用contentSize.height调整该值: 
 [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) { if (constraint.firstAttribute == NSLayoutAttributeHeight) { constraint.constant = contentSize.height; *stop = YES; } }]; 
 最后要做的是告诉超类updateConstraints 。 
 [super updateConstraints]; 
现在我们的class级看起来像:
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]; } 
漂亮干净,对吧? 而且您不必在控制器中处理该代码!
可是等等! 没有animation!
 你可以很容易地animation变化,使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.scrollEnabled = false 
除此之外不需要做任何事情。
 你有没有尝试[textView sizeThatFits:textView.bounds] ? 
 编辑:sizeThatFits返回的大小,但不实际调整组件大小。 我不确定这是你想要的,或者如果[textView sizeToFit]更多的是你要找的。 无论哪种情况,我都不知道它是否能够完美地符合你想要的内容,但是这是第一个尝试的方法。 
 另一种方法是使用NSString方法查找特定string将要占用的大小: 
 -(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size 
这将返回适合给定string的矩形的大小。 通过所需宽度和最大高度的尺寸,然后您可以查看返回的高度以适合文本。 有一个版本可以让你指定换行符模式。
然后,您可以使用返回的大小来更改视图的大小以适应。
 如果你没有方便的UITextView (例如,你正在调整表格视图单元格大小),你将不得不通过测量string来计算大小,然后计算UITextView每边的8点填充。 例如,如果您知道文本视图的所需宽度并想要找出相应的高度: 
 NSString * string = ...; CGFloat textViewWidth = ...; UIFont * font = ...; CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000); size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8; 
在这里,每个8是占四个填充边缘之一,而100000只是一个非常大的最大尺寸。
 在实践中,您可能需要添加一个额外的font.leading到高度; 这会在文本下面添加一个空白行,如果在文本视图下方直接显示可视化控件,这可能会更好一些。 
以下事情已经足够了:
-  只记得为你的UITextView设置滚动为NO :
  
 
- 正确设置自动布局约束。
 你甚至可以使用UITableViewAutomaticDimension 。 
我们可以通过约束来实现。
-  为UITextView设置高度约束。   
2.创buildIBOutlet的高度约束。
  @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; }]; } 
然后像这样更新你的约束:)
结合迈克·麦克马斯特的回答,你可能想要做一些事情:
 [myTextView setDelegate: self]; ... - (void)textViewDidChange:(UITextView *)textView { if (myTextView == textView) { // it changed. Do resizing here. } } 
我发现了一种方法来根据文本里面的文本来调整文本字段的高度,并根据文本字段的高度在它下面安排一个标签! 这是代码。
 UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)]; NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different."; _textView.text = str; [self.view addSubview:_textView]; CGRect frame = _textView.frame; frame.size.height = _textView.contentSize.height; _textView.frame = frame; UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)]; lbl.text = @"Hello!"; [self.view addSubview:lbl]; 
使用自动布局和你的sizetofit不工作的人,那么请检查你的宽度约束一次。 如果你错过了宽度约束,那么高度将是准确的。
不需要使用任何其他的API。 只有一条线可以解决所有问题。
 [_textView sizeToFit]; 
在这里,我只关心高度,保持宽度不变,错过了Storyboard中TextView的宽度约束。
这是为了显示服务的dynamic内容。
希望这可能会帮助..
从iOS 8开始,可以使用UITableView的自动布局function来根据自定义代码自动调整UITextView的大小。 我已经在github上做了一个项目来certificate这一点,但这里是关键:
- UITextView必须禁用滚动function,您可以通过编程或通过界面生成器进行操作。 如果启用了滚动,则不会resize,因为滚动可以查看较大的内容。
-  在UITableViewController的viewDidLoad中,必须为estimatedRowHeight设置一个值,然后将rowHeight设置为UITableViewAutomaticDimension。
 - (void)viewDidLoad { [super viewDidLoad]; self.tableView.estimatedRowHeight = self.tableView.rowHeight; self.tableView.rowHeight = UITableViewAutomaticDimension; } 
- 项目部署目标必须是iOS 8或更高版本。
这里是@jhibberd的快速版本
  let cell:MsgTableViewCell! = self.tableView.dequeueReusableCellWithIdentifier("MsgTableViewCell", forIndexPath: indexPath) as? MsgTableViewCell cell.msgText.text = self.items[indexPath.row] var fixedWidth:CGFloat = cell.msgText.frame.size.width var size:CGSize = CGSize(width: fixedWidth,height: CGFloat.max) var newSize:CGSize = cell.msgText.sizeThatFits(size) var newFrame:CGRect = cell.msgText.frame; newFrame.size = CGSizeMake(CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), newSize.height); cell.msgText.frame = newFrame cell.msgText.frame.size = newSize return cell 
 当我需要使UITextView文本适合特定区域时,这很好地工作: 
 //文本必须已经添加到子视图,否则contentviewsize将会出错。
 - (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;
     }
    如果(pointSize!= font.pointSize)
         NSLog(@“从%.1f到%.1f的字体”,pointSize,tv.font.pointSize);
 }
 对于iOS 7.0,不是将frame.size.height设置为contentSize.height (目前什么都不做),而是使用[textView sizeToFit] 。 
看到这个问题 。
我回顾了所有的答案,都保持固定的宽度,只调整高度。 如果你想调整宽度,你可以很容易地使用这种方法:
所以当configuration你的文本视图,设置滚动禁用
 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) } 
输出:
  
 
  
 
希望这可以帮助:
 - (void)textViewDidChange:(UITextView *)textView { CGSize textSize = textview.contentSize; if (textSize != textView.frame.size) textView.frame.size = textSize; } 
如果有任何其他的到这里,这个解决scheme为我工作,1“Ronnie Liew”+4“user63934”(我的文本从web服务到达):注意1000(在我的情况下,没有什么可以这么大)
 UIFont *fontNormal = [UIFont fontWithName:FONTNAME size:FONTSIZE]; NSString *dealDescription = [client objectForKey:@"description"]; //4 CGSize textSize = [dealDescription sizeWithFont:fontNormal constrainedToSize:CGSizeMake(containerUIView.frame.size.width, 1000)]; CGRect dealDescRect = CGRectMake(10, 300, containerUIView.frame.size.width, textSize.height); UITextView *dealDesc = [[[UITextView alloc] initWithFrame:dealDescRect] autorelease]; dealDesc.text = dealDescription; //add the subview to the container [containerUIView addSubview:dealDesc]; //1) after adding the view CGRect frame = dealDesc.frame; frame.size.height = dealDesc.contentSize.height; dealDesc.frame = frame; 
那就是……干杯
我发现根据文本的大小重新调整UITextView的高度的最佳方式。
 CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0] constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX)]; 
或者你可以使用
 CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0] constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX) lineBreakMode:NSLineBreakByTruncatingTail]; 
对于那些希望textview实际上移动并保持底线位置的人
 CGRect frame = textView.frame; frame.size.height = textView.contentSize.height; if(frame.size.height > textView.frame.size.height){ CGFloat diff = frame.size.height - textView.frame.size.height; textView.frame = CGRectMake(0, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height); } else if(frame.size.height < textView.frame.size.height){ CGFloat diff = textView.frame.size.height - frame.size.height; textView.frame = CGRectMake(0, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height); } 
唯一能够工作的代码是在上面的jhibberd回答中使用“SizeToFit”的代码,但实际上,除非您在ViewDidAppear中调用它或将其连接到UITextView文本更改的事件,否则它将不会启动。
基于Nikita Took的回答,我来到了Swift中的以下解决scheme,该解决scheme使用自动布局在iOS 8上工作:
  descriptionTxt.scrollEnabled = false descriptionTxt.text = yourText var contentSize = descriptionTxt.sizeThatFits(CGSizeMake(descriptionTxt.frame.size.width, CGFloat.max)) for c in descriptionTxt.constraints() { if c.isKindOfClass(NSLayoutConstraint) { var constraint = c as! NSLayoutConstraint if constraint.firstAttribute == NSLayoutAttribute.Height { constraint.constant = contentSize.height break } } } 
Swift的答案:下面的代码计算你的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))) 
 现在,您可以将myTextHeight的高度设置为myTextHeight 
 如果您需要在staticTableViewdynamic调整staticTableView和tableViewCell大小,这里是答案 
这个方法似乎适用于ios7
  // Code from apple developer forum - @Steve Krulewitz, @Mark Marszal, @Eric Silverberg - (CGFloat)measureHeight { if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) { CGRect frame = internalTextView.bounds; CGSize fudgeFactor; // The padding added around the text on iOS6 and iOS7 is different. fudgeFactor = CGSizeMake(10.0, 16.0); frame.size.height -= fudgeFactor.height; frame.size.width -= fudgeFactor.width; NSMutableAttributedString* textToMeasure; if(internalTextView.attributedText && internalTextView.attributedText.length > 0){ textToMeasure = [[NSMutableAttributedString alloc] initWithAttributedString:internalTextView.attributedText]; } else{ textToMeasure = [[NSMutableAttributedString alloc] initWithString:internalTextView.text]; [textToMeasure addAttribute:NSFontAttributeName value:internalTextView.font range:NSMakeRange(0, textToMeasure.length)]; } if ([textToMeasure.string hasSuffix:@"\n"]) { [textToMeasure appendAttributedString:[[NSAttributedString alloc] initWithString:@"-" attributes:@{NSFontAttributeName: internalTextView.font}]]; } // NSAttributedString class method: boundingRectWithSize:options:context is // available only on ios7.0 sdk. CGRect size = [textToMeasure boundingRectWithSize:CGSizeMake(CGRectGetWidth(frame), MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil]; return CGRectGetHeight(size) + fudgeFactor.height; } else { return self.internalTextView.contentSize.height; } }