sizeWithFont 메소드는 더 이상 사용되지 않습니다. boundingRectWithSize가 예기치 않은 값을 반환합니다.


82

iOS7에서는 sizeWithFont더 이상 사용되지 않으므로 boundingRectWithSize(CGRect 값을 반환하는) 사용하고 있습니다. 내 코드 :

 UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

 CGSize maximumLabelSize = CGSizeMake(310, 9999);

 CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                             options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{NSFontAttributeName:fontText}
                             context:nil];

 expectedLabelSize = CGSizeMake(textRect.size.width, textRect.size.height);

에서를 사용할 때와 다른 크기 인 textRect내 . 이 문제를 어떻게 해결할 수 있습니까?maximumLabelSizesizeWithFont


시스템 글꼴이나 Helvetica뿐만 아니라 모든 글꼴에서이 문제가 발생합니다.
Nirav 자이나교

어떻게하는지 아십니까?
Nirav Jain

글꼴 이름, 텍스트 및 크기 불일치에 대한 구체적인 예가 도움이 될 수 있습니다.
에이코

항상 올바른 높이를 반환하는 attributeString의 높이를 계산하기 위해 iOS6에서 CTFramesetterSuggestFrameSizeWithConstraints를 사용했습니다. iOS7에서 CTFramesetterSuggestFrameSizeWithConstraints와 boundingRectWithSize는 모두 잘못된 높이 결과를 제공합니다. iOS7에 도입 된 버그이며 아직 해결책이없는 것 같습니다.
Arnold Tang

임 또한 tttattributedlabel을 사용하는 것이 더 나은 동일한 문제에 직면하고 있습니다
Sri ..

답변:


151

새 라벨을 만들고 사용하는 것은 어떻습니까 sizeThatFit:(CGSize)size??

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:@"YOUR FONT's NAME" size:16];
gettingSizeLabel.text = @"YOUR LABEL's TEXT";
gettingSizeLabel.numberOfLines = 0;
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);

CGSize expectSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

편집 :이 상단 코드는 iOS 7 이상에 적합하지 않으므로 아래를 사용하십시오.

CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                         options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                         attributes:@{NSFontAttributeName:fontText}
                         context:nil];

이 방법은 문자열에 (<OL>, <LI>)와 같은 HTML 엔티티를 추가 할 때 작동하지 않습니다.
Nirav 자이나교

내 대답을 다시 확인하십시오! numberOfLines 속성을 놓쳤습니다! 죄송합니다!
Quang Hà 2013 년

1
시간 및 검색 시간, 실험 죽은 엔드 후이 유일한 해결책입니다 iOS7에와 자 마린 / Monotouch에 대한 작품
마이클 로드리게스

26
글꼴 크기를 계산하기 위해 라벨을 만드시겠습니까? 너무 낭비입니다!
Ossir 2014-07-02

13
@Ossir, 더 좋은 아이디어가 있습니까?
Luda 2014

36

답변 에서 제안하는 방법에 추가 옵션을 제공해야 할 수도 있습니다 .

CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                                         options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                      attributes:@{NSFontAttributeName: fontText}
                                         context:nil];

3
boundingRectWithSize깨진 것 같습니다 . iOS 7, 7.1.1에서 테스트했는데 올바른 결과가 아닙니다.
RaffAl 2014

이것은 나를 위해 작동하지 않았지만 NSAttributedString에서 boundingRectWithSize를 사용하고 대신 내 글꼴 속성을 문자열에 추가하면 작동했습니다.
Sheepdogsheep

12
여러분, Apple 성명을 잊지 마세요 . iOS 7 이상에서이 메서드는 (반환 된 CGRect의 크기 구성 요소에서) 분수 크기를 반환합니다. 반환 된 크기를 사용하여 뷰 크기를 조정하려면 ceil 함수를 사용하여 가장 가까운 더 높은 정수로 값을 올려야합니다.
SoftDesigner

2
ceil은 나에게 충분하지 않았습니다. 그러나 ceil을 사용하고 0.5를 더하는 것이 트릭을 수행한다는 것을 발견했습니다
dwery

15

내 작업 코드 스 니펫은 다음과 같습니다.

NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];

NSString *headline  = [dict objectForKey:@"title"];  
UIFont *font        = [UIFont boldSystemFontOfSize:18];  
CGRect  rect        = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];

CGFloat height      = roundf(rect.size.height +4)

계산 된 높이에 4px를 추가했습니다.이 4px가 없으면 한 줄이 누락 되었기 때문입니다.

이 코드 조각을 tableView에서 사용하고 NSNumbers 배열에 "높이"를 추가하면 기본 textLabel에 대한 올바른 셀 높이를 얻습니다.

textLabel의 텍스트 아래에 더 많은 공간을 원하면 4 픽셀을 더 추가합니다.

**** 업데이트 ****

저는 "40px의 너비 버그"에 동의하지 않습니다. 4px가 글자와 한 줄의 경계 사이의 기본 높이이기 때문에 누락 된 높이의 4px라고 외칩니다. UILabel로 확인할 수 있으며, 글꼴 크기가 16 인 경우 UILabel 높이가 20이 필요합니다.

그러나 마지막 줄에 "g"가 없거나 그 안에 아무것도 없으면 측정 값이 4px의 높이를 놓칠 수 있습니다.

나는 약간의 방법으로 그것을 다시 확인했고, 내 라벨의 정확한 높이는 20,40 또는 60이고 오른쪽 너비는 300px 미만입니다.

iOS6 및 iOS7을 지원하려면 내 방법을 사용할 수 있습니다.

- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (iosVersion >= 7.0) {
        rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
        CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
    }
    NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
    return rect.size.height;
}

**** 업그레이드 ****

귀하의 의견 덕분에 다음과 같이 기능을 업그레이드했습니다. sizeWithFont는 더 이상 사용되지 않으며 XCode에서 경고를 받게되므로이 특정 함수 호출 / 코드 블록에 대한 경고를 제거하기 위해 diagnostic-pragma-code를 추가했습니다.

- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
    CGRect rect;

    if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
    }
    else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
        rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
    }
    return ceil(rect.size.height);
}

4px 주제 : 사용하는 글꼴 및 글꼴 두께에 따라 계산에서 다른 높이 값을 반환합니다. 필자의 경우 글꼴 크기가 16.0 인 HelveticaNeue-Medium은 한 줄의 경우 20.0의 줄 높이를 반환하지만 두 줄의 경우 39.0, 4 줄의 경우 78px-> 줄 2로 시작하는 모든 줄에 대해 1px 누락-하지만 원하는 경우 모든 라인에 대해 fontsize + 4px 라인 스페이스를 가지려면 높이 결과를 얻어야합니다.
코딩하는 동안 명심하십시오!
아직이 "문제"에 대한 기능이 없지만 완료되면이 게시물을 업데이트하겠습니다.


1
float 값을 확인하는 대신 [text respondsToSelector : @selector (boundingRectWithSize : options : attributes : context :)]를 사용해야합니다.
Samah 2014

1
그것은이 응답에 천장을 만들다 대신 + 4PT의 기능, 모양을 사용하는 것이 좋습니다 stackoverflow.com/a/23563152/667483
서프 라이더

2

내가 올바르게 이해한다면, 당신은 sizeWithFont로 얻을 수있는 크기를 얻는 방법으로 boundingRectWithSize를 사용하고 있습니까 (CGRect가 아닌 CGSize를 직접 원한다는 의미)?

이것은 당신이 찾고있는 것 같습니다.

더 이상 사용되지 않는 sizeWithFont 대체 : iOS 7에서?

sizeWithFont 대신 sizeWithAttributes :를 사용하여 크기를 가져옵니다.

다음과 같은 것을 사용하여 여전히 잘못된 크기를 얻습니까?

UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
                    // you can use your font.

expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];

하지만 CGSize maximumLabelSize = CGSizeMake (310, 9999)를 어떻게 사용할 수 있습니까? 정확한 높이와 너비가 필요합니다.
Nirav Jain

1
sizeWithAttributes : 너비 / 높이를 제한하는 속성이 있습니까?
Nirav 자이나교

죄송합니다. 문제가 무엇인지 모르겠습니다. 글꼴 크기로 레이블 크기를 조정하고 싶지만 올바르게 이해하면 최대 높이보다 크지 않습니다. 당신은 sizeWithFont로 그렇게 할 수 있다고 말하지만,이 방법이 더 이상 사용되지 않기 때문에 대안을 원합니다. 맞습니까? sizeWithFont :를 사용했던 것과 같은 방식으로 sizeWithAttribues :를 연결할 수 있어야합니다. sizeWithFont를 사용할 때 레이블 크기를 어떻게 제한 했습니까? sizeWithFont를 사용하여 작동하던 코드를 게시 할 수 있습니까?
vinaut

2
그는 sizeWithFont : constrainedToSize : lineBreakMode :를 사용하고 있었고 constrainedToSize 값을 sizeWithAttributes에 전달할 방법이 없습니다.
zh.

2

@SoftDesigner의 의견이 저에게 효과적이었습니다.

CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
                                                       context:nil];
result = ceil(descriptionRect.size.height);

1

-boundingRectWithSize : options : attributes : context : method 를 사용하는 대신 iOS 7.0 에서 레이블 런타임 sizewithfont의 크기를 찾는 데 더 이상 사용되지 않습니다 .

아래 코드와 같이 사용할 수 있습니다.

CGSize constraint = CGSizeMake(MAXIMUM_WIDHT, TEMP_HEIGHT);
NSRange range = NSMakeRange(0, [[self.message body] length]);

NSDictionary *attributes = [YOUR_LABEL.attributedText attributesAtIndex:0 effectiveRange:&range];
CGSize boundingBox = [myString boundingRectWithSize:constraint options:NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
int numberOfLine = ceil((boundingBox.width) / YOUR_LABEL.frame.size.width);
CGSize descSize = CGSizeMake(ceil(boundingBox.width), ceil(self.lblMessageDetail.frame.size.height*numberOfLine));

CGRect frame=YOUR_LABEL.frame;
frame.size.height=descSize.height;
YOUR_LABEL.frame=frame;

여기에서 높이 또는 너비를 찾기 위해 너비를 최대 길이로 제공해야합니다.

나를 위해 일하는 이것을 시도하십시오.

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