[ios] iOS7 UITextView contentsize.height 대안

iOS 6.1에서 iOS 7로 앱 중 하나를 이식 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];
    }
}

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:)])‌


답변

이것은 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을 잊지 마세요.