Ersatz für veraltete -sizeWithFont: ConstrainedToSize: lineBreakMode: in iOS 7?


146

In iOS 7 ist die Methode:

- (CGSize)sizeWithFont:(UIFont *)font
     constrainedToSize:(CGSize)size
         lineBreakMode:(NSLineBreakMode)lineBreakMode 

und die Methode:

- (CGSize)sizeWithFont:(UIFont *)font

sind veraltet. Wie kann ich ersetzen

CGSize size = [string sizeWithFont:font
                 constrainedToSize:constrainSize
                     lineBreakMode:NSLineBreakByWordWrapping];

und:

CGSize size = [string sizeWithFont:font];

2
Die Ersatzmethode ist -sizeWithAttributes:.
Holex

ok holex danke, aber wie kann ich eine Schriftart vom Label wie ein NSDIctionary verwenden? Wenn mein Code wie folgt lautet: sizeWithFont: customlabel.font; die Leere fragen "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo

1
Hier ist die offizielle Dokumentation, wie Sie Attribute definieren können: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

Antworten:


219

Sie könnten dies versuchen:

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:FONT}
                                 context:nil];

CGSize size = textRect.size;

Ändern Sie einfach "FONT" in "[UIFont font ....]".


13
Und wo erwähnen Sie NSLineBreakByWordWrapping? Wo ist es hingegangen?
user4951

31
NSLineBreakByWordWrappingwürde innerhalb eines gehen NSParagraphStyle. Also zum Beispiel: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;In den Attributen müssten Sie dann hinzufügen NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich

1
@ffried in meinem Fall Durch Hinzufügen des Absatzstils mit einem anderen Zeilenumbruch als NSLineBreakByWordWrapping wurde die Größe für nur eine Zeile berechnet. Irgendwelche Gedanken?
Manicaesar

9
Vergessen Sie nicht, dass boundingRectWithSize:options:attributes:context:Bruchwerte zurückgegeben werden. Sie tun müssen , ceil(textRect.size.height)und ceil(textRect.size.width)jeweils die reale Höhe / Breite zu erhalten.
Florian Friedrich

20
Was zum Teufel ist BOLIVIASize?
JRam13

36

Da wir sizeWithAttributes nicht für alle iOS-Versionen größer als 4,3 verwenden können, müssen wir bedingten Code für 7.0 und frühere iOS-Versionen schreiben.

1) Lösung 1:

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
   CGSize size = CGSizeMake(230,9999);
   CGRect textRect = [specialityObj.name  
       boundingRectWithSize:size
                    options:NSStringDrawingUsesLineFragmentOrigin
                 attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
                    context:nil];
   total_height = total_height + textRect.size.height;   
}
else {
   CGSize maximumLabelSize = CGSizeMake(230,9999); 
   expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous. 
   total_height = total_height + expectedLabelSize.height;
}

2) Lösung 2

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement

CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

Die erste Lösung besteht darin, manchmal nicht den richtigen Höhenwert zurückzugeben. Verwenden Sie also eine andere Lösung. das wird perfekt funktionieren.

Die zweite Option ist recht gut und funktioniert in allen iOS-Versionen ohne bedingten Code reibungslos.


1
warum 230, 999? Woher bekommen Sie die Nummer>
user4951

1
Der 230 kann eine beliebige Nummer sein. Es repräsentiert die Breite, die Sie für Ihr Etikett wünschen. Der 9999 würde ich lieber durch INFINITY oder MAXFLOAT ersetzen.
Florian Friedrich

Die zweite Lösung funktioniert wie ein Zauber. Danke Nirav.
Jim

1
"[AppHandlers zHandler]" gibt einen Fehler aus. "Nicht deklarierte Bezeichner". Wie kann man das lösen?
Dimple

9

Hier ist eine einfache Lösung:

Bedarf :

CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];

Jetzt Da die constrainedToSizeusage:lineBreakMode:Nutzung in iOS 7.0 veraltet ist :

CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];

Jetzt wird die Verwendung in einer größeren Version von iOS 7.0 wie folgt sein:

// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];

//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

7

Im Folgenden finden Sie zwei einfache Methoden, die diese beiden veralteten Methoden ersetzen.

Und hier sind die relevanten Referenzen:

Wenn Sie NSLineBreakByWordWrapping verwenden, müssen Sie den NSParagraphStyle nicht angeben, da dies die Standardeinstellung ist: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index. html # // apple_ref / occ / clm / NSParagraphStyle / defaultParagraphStyle

Sie müssen die Obergrenze der Größe ermitteln, damit die Ergebnisse der veralteten Methoden übereinstimmen. https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context :

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {    
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
    CGRect textRect = [text boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:@{NSFontAttributeName: font}
                                     context:nil];
    return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}

6

In den meisten Fällen habe ich die Methode sizeWithFont: ConstrainedToSize: lineBreakMode: verwendet , um die Mindestgröße für ein UILabel zu schätzen zu um seinen Text aufzunehmen (insbesondere, wenn das Etikett in einer UITableViewCell platziert werden muss) ...

... Wenn dies genau Ihre Situation ist , können Sie einfach die folgende Methode verwenden:

CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;

Hoffe das könnte helfen.


5
In der Dokumentation von Apple heißt es, dass Sie diese Methode nicht direkt aufrufen sollten.
Barlow Tucker

Zumindest in der Dokumentation zum iOS 7 SDK nicht erwähnt.
Rivera

3
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil];
CGSize stringSize= new.size;

3
Willkommen bei StackOverFlow. Posten Sie nicht noch einmal dieselbe Antwort. Wenn Sie einer Antwort etwas hinzufügen müssen, geben Sie einen Kommentar ab oder bearbeiten Sie die Antwort.
Ramaraj T

ok..Ich werde das nächste Mal berücksichtigen. Vielen Dank für Ihren Rat.
user3575114

2

[Akzeptierte Antwort funktioniert gut in einer Kategorie. Ich überschreibe die veralteten Methodennamen. Ist das eine gute Idee? Scheint ohne Beschwerden in Xcode 6.x zu funktionieren]

Dies funktioniert, wenn Ihr Bereitstellungsziel 7.0 oder höher ist. Kategorie istNSString (Util)

NSString + Util.h

- (CGSize)sizeWithFont:(UIFont *) font;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;

NSString + Util.m

- (CGSize)sizeWithFont:(UIFont *) font {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    return [self sizeWithAttributes:fontAsAttributes];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    CGRect retVal = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:fontAsAttributes context:nil];
    return retVal.size;
}

0
UIFont *font = [UIFont fontWithName:@"Courier" size:16.0f];

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;

NSDictionary *attributes = @{ NSFontAttributeName: font,
                    NSParagraphStyleAttributeName: paragraphStyle };

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:attributes
                                 context:nil];

CGSize size = textRect.size;

aus zwei Antworten 1 + 2

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.