IOS 6.1からiOS 7にアプリの1つを移植しています。幅が固定されているUITextView
があるレイアウトを使用していますが、高さはコンテンツサイズに基づいています。 iOS 6.1の場合、contentsize.heightを確認し、textviewのフレームの高さに設定するだけで十分でしたが、iOS 7では機能しません。
次に、固定幅で、表示されているテキストに基づいて動的な高さでUITextView
を作成するにはどうすればよいですか?
注:これらのビューは、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)
前のテストSYSTEM_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;
この小さな機能を使用する
-(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)
_textView.textContainerInset = UIEdgeInsetsZero;
_textView.textContainer.lineFragmentPadding = 0;
LineFragmentPaddingを忘れないでください
@ -Ana、@-Blake HamiltonのソリューションSwift。
var contentHeight: CGFloat = textView.sizeThatFits(textView.frame.size).height
私にとって良いことは、contentSize
がfalseに設定されているときに、これが正しいisScrollEnable
を返すことでした。 falseに設定すると、コンテンツサイズではなくテキストビューのフレームサイズが返されます。
簡単な解決策-textView.isScrollEnabled = false
は、別のスクロールビュー、またはUITableViewAutomaticDimension
を含むtableViewセル内で完璧に動作します