我正在将一个应用程序从iOS 6.1移植到iOS7。我正在使用一种布局,该布局的UITextView
宽度固定,但是高度取决于其contentsize。对于iOS 6.1,检查contentsize.height并将其设置为textview的框架高度就足够了,但是在iOS 7上不起作用。
然后,如何UITextView
根据显示的文字创建具有固定宽度但动态高度的?
注意:我是通过代码而不是使用Interface Builder创建这些视图的。
我正在将一个应用程序从iOS 6.1移植到iOS7。我正在使用一种布局,该布局的UITextView
宽度固定,但是高度取决于其contentsize。对于iOS 6.1,检查contentsize.height并将其设置为textview的框架高度就足够了,但是在iOS 7上不起作用。
然后,如何UITextView
根据显示的文字创建具有固定宽度但动态高度的?
注意:我是通过代码而不是使用Interface Builder创建这些视图的。
Answers:
使用以下代码,您可以根据固定宽度更改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];
}
}
您可以将其添加到SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
项目中的prefix.pch文件中,如下所示:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
您还可以通过以下方式替换之前的测试SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)
:
if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])
NSStringDrawingUsesFontLeading
是多余的
这对我适用于iOS6和7:
CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)];
self.myTextView.height = textViewSize.height;
textView.bounds.size.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;
使用这个小功能
-(CGSize) getContentSize:(UITextView*) myTextView{
return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)];
}
我的最终解决方案基于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);
}
有更简单的解决方案,使用此方法:
+(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)
usedRectForTextContainer
方法返回相同的高度时。