web-dev-qa-db-ja.com

iOS7 UITextView contentsize.heightの代替

IOS 6.1からiOS 7にアプリの1つを移植しています。幅が固定されているUITextViewがあるレイアウトを使用していますが、高さはコンテンツサイズに基づいています。 iOS 6.1の場合、contentsize.heightを確認し、textviewのフレームの高さに設定するだけで十分でしたが、iOS 7では機能しません。

次に、固定幅で、表示されているテキストに基づいて動的な高さでUITextViewを作成するにはどうすればよいですか?

注:これらのビューは、Interface Builderではなくコードから作成しています。

78
Zoltan Varadi

次のコードを使用すると、固定幅に応じて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:)])‌
180
Jordan Montel

これはiOS6と7でうまくいきました:

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

IOS7では、UITextViewNSLayoutManagerを使用してテキストをレイアウトします。

// 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;
20
nova

この小さな機能を使用する

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

私の最終的なソリューションは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);
}
3
xZenon

この方法を使用した簡単な解決策があります。

+(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)

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

LineFragmentPaddingを忘れないでください

1
ChaoWang

@ -Ana、@-Blake HamiltonのソリューションSwift

var contentHeight: CGFloat = textView.sizeThatFits(textView.frame.size).height

私にとって良いことは、contentSizeがfalseに設定されているときに、これが正しいisScrollEnableを返すことでした。 falseに設定すると、コンテンツサイズではなくテキストビューのフレームサイズが返されます。

0
Baran

簡単な解決策-textView.isScrollEnabled = falseは、別のスクロールビュー、またはUITableViewAutomaticDimensionを含むtableViewセル内で完璧に動作します

0
Kirow