sizeWithFont yöntemi kullanımdan kaldırılmıştır. boundingRectWithSize beklenmedik bir değer döndürür


82

İOS7'de sizeWithFontkullanımdan kaldırıldı, bu yüzden kullanıyorum boundingRectWithSize(bu bir CGRect değeri döndürüyor). Kodum:

 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);

İçinde textRect, kullandığımdan daha büyük maximumLabelSize, farklı bir boyut alıyorum sizeWithFont. Bu sorunu nasıl çözebilirim?


Bu sorunu sadece sistem yazı tipi veya Helvetica değil tüm yazı tipleriyle alıyorum.
Nirav Jain

bunu nasıl yapacağına dair bir fikrin var mı?
Nirav Jain

Yazı tipi adı, metin ve uyumsuz boyutlar için somut bir örnek yardımcı olabilir.
Eiko

Eskiden iOS6'da CTFramesetterSuggestFrameSizeWithConstraints'i her zaman doğru yüksekliği döndüren attributedString'in yüksekliğini hesaplamak için kullanırdım. İOS7'de, hem CTFramesetterSuggestFrameSizeWithConstraints hem de boundingRectWithSize bana yanlış yükseklik sonucu veriyor. Bahse girerim iOS7'de ortaya çıkan bir hatadır ve henüz bir çözüm görünmüyor.
Arnold Tang

Ben de aynı sorunla karşı karşıyayım, tttattributedlabel
Sri ..

Yanıtlar:


151

Yeni etiket oluşturup sizeThatFit:(CGSize)size?? kullanmaya ne dersiniz ?

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];

Düzenleme: Bu üst kod, ios 7 ve üzeri için uygun değildir, bu nedenle lütfen aşağıdakileri kullanın:

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

string'e (<OL>, <LI>) gibi HTML varlıkları eklerken bu yöntem çalışmıyor.
Nirav Jain

lütfen cevabımı tekrar kontrol edin! NumberOfLines özelliğini kaçırdım! afedersiniz!
Quang Hà

1
Saatler ve saatler süren arama, deneme ve çıkmazların ardından, iOS7 ve Xamarin / Monotouch için çalışan tek çözüm budur
Michael Rodrigues

26
Yazı tipi boyutunu hesaplamak için etiket mi oluşturuyorsunuz? Bu çok israf!
Ossir

13
@Ossir, daha iyi bir fikrin var mı?
Luda

36

Belki de bu cevapta önerilen yönteme ek seçenek sağlamanız gerekir :

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

3
boundingRectWithSizeKırık gibi görünüyor . İOS 7, 7.1.1'de test ettim ve doğru sonuçlar vermiyor.
RaffAl

Bu benim için işe yaramadı, ancak bir NSAttributedString'de boundingRectWithSize kullanarak ve bunun yerine font özniteliğimi dizeye eklemek işe yaradı.
Sheepdogsheep

12
Beyler, Apple ifadesini unutmayın: iOS 7 ve sonraki sürümlerde, bu yöntem kesirli boyutları döndürür (döndürülen CGRect'in boyut bileşeninde); boyut görünümlerine döndürülen bir boyutu kullanmak için, ceil işlevini kullanarak değerini en yakın yüksek tam sayıya yükselt seçeneğini kullanmanız gerekir.
SoftDesigner

2
ceil benim için yeterli değildi, ancak ceil kullanmanın ve 0.5 eklemenin hile yaptığını
öğrendim

15

İşte çalışma kod pasajım:

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)

Hesaplanan yüksekliğe 4px ekledim, çünkü bu 4px olmadan bir satır eksik.

Bu kod parçacığını bir tableView içinde kullanıyorum ve bir NSNumber dizisine "yüksekliği" ekliyorum ve varsayılan textLabel için doğru hücre yüksekliğini alıyorum.

TextLabel'deki metnin altında daha fazla boşluk istiyorsanız 4 piksel daha ekleyin.

**** GÜNCELLEME ****

"40px genişlik hatası" na katılmıyorum, 4px eksik yüksekliğin 4px olduğunu haykırıyorum çünkü 4px bir harf ile tek bir satırın sınırı arasındaki boşluğun varsayılan yüksekliğidir. Bunu bir UILabel ile kontrol edebilirsiniz, 16 yazı tipi boyutu için 20 UILabel yüksekliğine ihtiyacınız vardır.

Ancak son satırınızda "g" veya herhangi bir şey yoksa, ölçüm 4px yüksekliği eksik olabilir.

Küçük bir yöntemle tekrar kontrol ettim, etiketim için doğru yükseklik 20,40 veya 60 ve doğru genişlik 300 pikselden az.

İOS6 ve iOS7'yi desteklemek için benim yöntemimi kullanabilirsiniz:

- (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;
}

**** YÜKSELT ****

Yorumlarınız sayesinde, işlevimi aşağıdaki gibi yükselttim. SizeWithFont kullanımdan kaldırıldığından ve XCode'da bir uyarı alacağınız için, bu özel işlev çağrısı / kod bloğu için uyarıyı kaldırmak için tanılama-pragma kodunu ekledim.

- (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 konusuna ek olarak: Kullandığınız yazı tipi ve yazı tipi ağırlığına bağlı olarak, hesaplama farklı yükseklik değerleri döndürür. Benim durumumda: 16.0 yazı tipi boyutuna sahip HelveticaNeue-Medium, tek bir satır için 20.0 satır yüksekliği, iki satır için 39.0, 4 satır için 78px - her satır için> 1px eksik - 2. satırdan başlayarak - ancak istediğiniz yazı tipi boyutunuzu + 4px satır aralığına sahip olmak için her satır için bir yükseklik sonucu almanız gerekir.
Lütfen kodlama sırasında bunu aklınızda bulundurun!
Henüz bu "sorun" için bir işlevim yok, ancak bitirdiğimde bu gönderiyi güncelleyeceğim.


1
Muhtemelen bir kayan değeri kontrol etmek yerine [text responsesToSelector: @selector (boundingRectWithSize: options: attributes: context :)] kullanmalısınız.
Samah

1
+ 4pt yerine tavan işlevini kullanmak daha iyidir, şu cevaba bakın stackoverflow.com/a/23563152/667483
surfrider

2

Doğru anladıysam, boundingRectWithSize kullanıyorsunuz: sadece sizeWithFont ile elde edeceğiniz boyutu elde etmenin bir yolu olarak (yani CGRect değil, doğrudan CGSize istiyorsunuz)?

Bu aradığınız şeye benziyor:

Kullanımdan kaldırılmış sizeWithFont için değiştirme: iOS 7'de mi?

SizeWithAttributes: boyutunu almak için, sizeWithFont'un yerini alacak şekilde kullanıyorlar.

Hala böyle bir şey kullanarak yanlış beden mi alıyorsunuz:

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

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

ancak CGSize maximumLabelSize = CGSizeMake (310, 9999) nasıl kullanabilirim? Doğru yüksekliğe ve genişliğe ihtiyacım var.
Nirav Jain

1
SizeWithAttributes: genişliğini / yüksekliğini kısıtlamasını söyleyen herhangi bir özellik var mı?
Nirav Jain

Üzgünüm ama sorunun ne olduğunu anlamadım. Etiketi yazı tipi boyutuyla boyutlandırmak istiyorsunuz, ancak doğru anladıysam maksimum yüksekliği aşmamak. Bunu sizeWithFont ile yapabileceğinizi söylüyorsunuz, ancak bu yöntem artık kullanılmadığına göre bir alternatif istiyorsunuz, değil mi? SizeWithAttribues: eklentisini sizeWithFont: kullandığınız şekilde yapabilmeniz gerekir. SizeWithFont'u kullanırken etiket boyutunu nasıl kısıtlıyordunuz? SizeWithFont kullanarak sizin için çalışan kodu gönderebilir misiniz?
vinaut

2
SizeWithFont: constrainedToSize: lineBreakMode: kullanıyordu ve constrainedToSize değerini sizeWithAttributes'a geçirmenin bir yolu yok.
zh.

2

@ SoftDesigner'ın yorumu benim için çalıştı

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

1

Etiket çalışma zamanı boyutunu bulmak için sizewithfont iOS 7.0 için kullanımdan kaldırıldı yerine kullanmak zorunda Bunun -boundingRectWithSize: seçenekleri: öznitelikler: Bağlam: yöntemini

aşağıdaki kod gibi kullanabilirsiniz

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;

burada yüksekliği veya genişliği bulmak için maksimum uzunluğa genişlik vermelisiniz.

bunu dene benim için çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.