iOS7 UITextView contentsize.height替代

我正在从iOS 6.1移植到iOS 7的应用程序之一。我正在使用一个布局,其中有一个固定宽度的UITextView ,但它的高度是基于其内容大小。 对于iOS 6.1来说,检查contentsize.height并将其设置为textview的框架高度就足够了,但在iOS 7上不起作用。

我怎样才能创build一个固定宽度的UITextView ,但基于它显示的文本的dynamic高度?

注意:我从代码创build这些视图,而不是使用Interface Builder。

使用以下代码,可以根据固定宽度更改UITextView的高度(它可以在iOS 7和以前的版本中使用):

 - (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width { UITextView *textView = [[UITextView alloc] init]; [textView setAttributedText:text]; CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)]; return size.height; } 

使用这个函数,你将获得一个NSAttributedString和一个固定宽度来返回所需的高度。

如果你想从具有特定字体的文本中计算框架,你需要使用下面的代码:

 - (CGSize)text:(NSString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { CGRect frame = [text boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:font} context:nil]; return frame.size; } else { return [text sizeWithFont:font constrainedToSize:size]; } } 

您可以在项目中的prefix.pch文件上添加SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO ,如下所示:

 #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 

您也可以通过以下方式replace之前的testingSYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)

 if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])‌ 

这适用于我的iOS6和7:

 CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)]; self.myTextView.height = textViewSize.height; 

在iOS7中, UITextView使用NSLayoutManager来布局文本:

 // If YES, then the layout manager may perform glyph generation and layout for a given portion of the text, without having glyphs or layout for preceding portions. The default is NO. Turning this setting on will significantly alter which portions of the text will have glyph generation or layout performed when a given generation-causing method is invoked. It also gives significant performance benefits, especially for large documents. @property(NS_NONATOMIC_IOSONLY) BOOL allowsNonContiguousLayout; 

禁用allowsNonContiguousLayout修复contentSize

 textView.layoutManager.allowsNonContiguousLayout = NO; 

使用这个小function

 -(CGSize) getContentSize:(UITextView*) myTextView{ return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)]; } 

我的最终解决scheme是基于HotJard的,但包括文本容器的顶部和底部插入,而不是使用2 * fabs(textView.contentInset.top):

 - (CGFloat)textViewHeight:(UITextView *)textView { return ceilf([textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height + textView.textContainerInset.top + textView.textContainerInset.bottom); } 

有更简单的解决scheme,使用这种方法:

 +(void)adjustTextViewHeightToContent:(UITextView *)textView; { if([[UIDevice currentDevice].systemVersion floatValue] >= 7.0f){ textView.height = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height+2*fabs(textView.contentInset.top); }else{ textView.height = textView.contentSize.height; } } 

UPD :仅用于显示文本(isEditable = NO)

  _textView.textContainerInset = UIEdgeInsetsZero; _textView.textContainer.lineFragmentPadding = 0; 

只是不要忘记lineFragmentPadding