แทนที่ -sizeWithFont: constrainedToSize: lineBreakMode: ใน iOS 7 หรือไม่


146

ใน iOS 7 วิธีการ:

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

และวิธีการ:

- (CGSize)sizeWithFont:(UIFont *)font

เลิกใช้แล้ว ฉันจะเปลี่ยนได้อย่างไร

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

และ:

CGSize size = [string sizeWithFont:font];

2
-sizeWithAttributes:วิธีการแทนคือ
holex

ok holex ขอบคุณ แต่ฉันจะใช้แบบอักษรจากป้ายกำกับเช่น NSDIctionary ได้อย่างไร ถ้ารหัสของฉันเป็นเช่น: sizeWithFont: customlabel.font; โมฆะถามว่า "sizeWithAttributes: <# (NSDictionary *) #>"
user_Dennis_Mostajo

1
นี่คือเอกสารอย่างเป็นทางการเกี่ยวกับวิธีที่คุณสามารถกำหนดแอตทริบิวต์: developer.apple.com/library/ios/documentation/UIKit/Reference/…
holex

คำตอบ:


219

คุณสามารถลองสิ่งนี้:

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

CGSize size = textRect.size;

เพียงแค่เปลี่ยน "FONT" สำหรับ "[UIFont font .... ]"


13
และคุณพูดถึง NSLineBreakByWordWrapping ที่ไหน? มันหายไปไหนเหรอ?
user4951

32
NSLineBreakByWordWrappingNSParagraphStyleจะไปภายใน ตัวอย่างเช่น: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;ในคุณสมบัติที่คุณจะต้องเพิ่มNSParagraphStyleAttributeName: paragraphStyle.copy...
ฟลอเรียนฟรีดริช

1
@ มีการรายงานแล้วในกรณีของฉันการเพิ่มย่อหน้าสไตล์ด้วยการแบ่งบรรทัดอื่นที่ไม่ใช่ NSLineBreakByWordWrapping ทำให้ขนาดคำนวณได้เพียงบรรทัดเดียว…ความคิดใด ๆ
manicaesar

9
อย่าลืมว่าboundingRectWithSize:options:attributes:context:คืนค่าเศษส่วน คุณต้องทำceil(textRect.size.height)และceil(textRect.size.width)ตามลำดับเพื่อให้ได้ความสูง / ความกว้างจริง
Florian Friedrich

20
อะไรคือสิ่งที่ทำให้เป็นก้อนโบลิเวีย?
JRam13

36

เนื่องจากเราไม่สามารถใช้ sizeWithAttributes สำหรับ iOS ทั้งหมดที่มากกว่า 4.3 เราต้องเขียนโค้ดแบบมีเงื่อนไขสำหรับ 7.0 และ iOS ก่อนหน้า

1) โซลูชันที่ 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) โซลูชัน 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];

ทางออกแรกคือบางครั้งไม่สามารถคืนค่าความสูงที่เหมาะสม ดังนั้นให้ใช้วิธีอื่น ซึ่งจะทำงานได้อย่างสมบูรณ์แบบ

ตัวเลือกที่สองค่อนข้างดีและทำงานได้อย่างราบรื่นใน iOS ทั้งหมดโดยไม่มีรหัสตามเงื่อนไข


1
ทำไม 230, 999 คุณจะได้รับหมายเลข>
user4951

1
230 สามารถเป็นตัวเลขใด ๆ ก็ได้ มันหมายถึงความกว้างที่คุณต้องการสำหรับฉลากของคุณ 9999 ฉันต้องการแทนที่ด้วย INFINITY หรือ MAXFLOAT
Florian Friedrich

วิธีที่สองทำงานได้อย่างมีเสน่ห์ ขอบคุณ Nirav
Jim

1
"[AppHandlers zHandler]" ให้ข้อผิดพลาด .. "Undeclared Identifiers" วิธีแก้นั้น
ลักยิ้มที่

9

นี่คือทางออกที่ง่าย:

ข้อกำหนด:

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

เนื่องจากconstrainedToSizeusage:lineBreakMode:การใช้งานเลิกใช้แล้วในiOS 7.0 :

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

ตอนนี้การใช้งานในiOS 7.0รุ่นที่สูงกว่าจะเป็น:

// 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

ด้านล่างนี้เป็นวิธีการง่ายๆสองวิธีที่จะแทนที่วิธีการทั้งสองที่เลิกใช้แล้ว

และนี่คือการอ้างอิงที่เกี่ยวข้อง:

หากคุณใช้ NSLineBreakByWordWrapping คุณไม่จำเป็นต้องระบุ NSParagraphStyle เนื่องจากเป็นค่าเริ่มต้น: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index HTML # // apple_ref / OCC / CLM / NSParagraphStyle / defaultParagraphStyle

คุณต้องรับขนาดของเพดานเพื่อให้ตรงกับผลลัพธ์ของเมธอดที่เลิกใช้แล้ว 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

ในกรณีส่วนใหญ่ฉันใช้วิธีsizeWithFont: constrainedToSize: lineBreakMode:เพื่อประเมินขนาดขั้นต่ำสำหรับUILabelเพื่อรองรับข้อความ (โดยเฉพาะเมื่อต้องวางฉลากไว้ใน UITableViewCell) ...

... หากนี่เป็นสถานการณ์ของคุณอย่างแน่นอนคุณสามารถใช้วิธีการ simpy:

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

หวังว่ามันจะช่วยได้


5
เอกสารของ Apple บอกว่าคุณไม่ควรเรียกวิธีนี้โดยตรง
บาร์โลว์ทักเกอร์

ไม่ได้กล่าวถึงในเอกสารประกอบ iOS 7 SDK เป็นอย่างน้อย
ริเวร่า

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
ยินดีต้อนรับสู่ StackOverFlow อย่าโพสต์คำตอบเดียวกันอีกครั้ง หากคุณต้องการเพิ่มคำตอบให้แสดงความคิดเห็นหรือทำการแก้ไขคำตอบ
Ramaraj T

ตกลง .. ฉันจะนำสิ่งนั้นไปพิจารณาในครั้งต่อไปขอขอบคุณสำหรับคำแนะนำของคุณ
user3575114

2

[คำตอบที่ได้รับการยอมรับทำงานได้ดีในหมวดหมู่ ฉันเขียนทับชื่อวิธีที่ไม่สอดคล้อง นี่เป็นความคิดที่ดีหรือไม่? ดูเหมือนว่าจะทำงานโดยไม่มีการร้องเรียนใน Xcode 6.x]

สิ่งนี้จะทำงานได้ถ้าเป้าหมายการปรับใช้ของคุณเป็น 7.0 หรือสูงกว่า ประเภทคือNSString (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;

จากสองคำตอบ1 + 2

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.