iOS7 UITextView contentsize.height 대안


78

iOS 6.1에서 iOS 7로 앱 중 하나를 이식 UITextView하고 있습니다. 너비가 고정 된 레이아웃을 사용하고 있지만 높이는 콘텐츠 크기를 기준으로합니다. iOS 6.1의 경우 contentsize.height를 확인하고 textview의 프레임 높이로 설정하면 충분했지만 iOS 7에서는 작동하지 않습니다.

그런 다음 UITextView표시되는 텍스트를 기반으로 고정 너비이지만 동적 높이로을 어떻게 만들 수 있습니까?

참고 : 저는 Interface Builder가 아니라 코드에서 이러한 뷰를 생성하고 있습니다.

답변:


180

다음 코드를 사용하면 고정 너비에 따라 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:)])‌

24 시간 후에 만 ​​줄 수 있습니다. 수 환자, 그것의 당신 :)
졸탄 Varadi

16
당신이 그 (것)들을 가져온 대답에 연결해야 하는가? stackoverflow.com/questions/18368567/...
앤드류 - 콜필드

@Jordan Montel, 다른 질문에 대해 고정 너비와 높이가있는 경우 할당 된 문자열에 가장 적합한 글꼴 크기를 어떻게 찾을 수 있습니까? iOS7에서도 비슷한 문제가 있습니다 (iOS6에서는 할 수 있습니다)
LiangWang

1
@Jacky : 시행 착오; 계산 된 높이가 너무 커질 때까지 크기를 1 씩 늘리거나 줄입니다. 또는 크기를 1000으로 만들고 자동으로 크기를 조정합니다.
Cœur 2013

이 대답은 이미 틀 렸습니다. 이러한 텍스트 필드에 많은 텍스트를 입력하십시오. 갑자기 잘못된 크기? 최소한 NSStringDrawingUsesFontLeading추가입니다
user2159978 dec.

42

이것은 iOS6 및 7에서 저에게 효과적이었습니다.

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

안녕하세요, 네의 워킹 나를 위해 ... 내가 대신 "txtviewHeight.contentSize.height"의 "txtviewHeight.frame.size.height"을 사용하고있다
마니

"UITextView"유형의 개체에서 속성 높이를 찾을 수없는 이유는 무엇입니까?
Hexark 14

@HexarktextView.bounds.size.height
사용자

21

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;

7
당신의 대답은 질문에 맞지 않지만 내 문제에 맞습니다. 나는 :) 투표를 그래서
vietstone

이것은 나를 위해 콘텐츠 크기를 수정하지 않습니다. 스크롤이 비활성화됩니다.
Dvole 2016-06-05

이 코드 조각은 내 문제를 해결했지만 생성 원인 방법이 귀하의 의견에서 무엇을 의미합니까?
Code Farmer

15

이 작은 기능을 사용하십시오

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

나를 위해 iOS6 및 iOS7에서 작동합니다. 감사!
Paul Brady

4

내 최종 솔루션은 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

이 방법을 사용하는 간단한 솔루션이 있습니다.

+(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 goto 두 번째 줄 usedRectForTextContainer메서드가 동일한 높이를 반환 할 때 .
Valerii Pavlov 2013 년

아, I'v 그냥 텍스트를 표시하기 위해 사용 될 수 있습니다
HotJard

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

lineFragmentPadding을 잊지 마세요.


0

간단한 솔루션- textView.isScrollEnabled = false 다른 스크롤 뷰 또는 tableView 셀 내부에서 완벽하게 작동합니다.UITableViewAutomaticDimension


0

@ Ana 's, @Blake Hamilton의 신속한 솔루션 .

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

나에게 좋은 점 은가 false로 설정 contentSize되었을 때 올바른을 반환한다는 것입니다 isScrollEnable. false로 설정하면 콘텐츠 크기 대신 텍스트보기의 프레임 크기가 반환됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.