Thay thế cho deprecated -sizeWithFont: ràng buộcToSize: lineBreakMode: trong iOS 7?


146

Trong iOS 7, phương thức:

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

và phương pháp:

- (CGSize)sizeWithFont:(UIFont *)font

bị phản đối Làm thế nào tôi có thể thay thế

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

và:

CGSize size = [string sizeWithFont:font];

2
phương pháp thay thế là -sizeWithAttributes:.
holex

ok holex cảm ơn, nhưng làm cách nào tôi có thể sử dụng phông chữ từ nhãn như NSDIctionary? nếu mã của tôi giống như: sizeWithFont: customlabel.font; void hãy hỏi "sizeWithAttribut: <# (NSDipedia *) #>"
user_Dennis_Mostajo

1
đây là tài liệu chính thức về cách bạn có thể xác định các thuộc tính: developer.apple.com/l
Library / ios / document / UIKit / Reference / /

Câu trả lời:


219

Bạn có thể thử điều này:

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

CGSize size = textRect.size;

Chỉ cần thay đổi "FONT" cho "[phông chữ UIFont ....]"


13
Và bạn đề cập đến NSLineBreakByWordWrapping ở đâu? Nó đã đi đâu?
dùng4951

31
NSLineBreakByWordWrappingsẽ đi trong vòng a NSParagraphStyle. Vì vậy, ví dụ: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;Trong các thuộc tính bạn cần thêm NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich

1
@ffried trong trường hợp của tôi thêm đoạnStyle với ngắt dòng khác với NSLineBreakByWordWrapping kích thước gây ra được tính cho chỉ một dòng Đá Bạn có suy nghĩ gì không?
manicaesar

9
Đừng quên rằng boundingRectWithSize:options:attributes:context:trả về giá trị phân số. Bạn cần phải làm ceil(textRect.size.height)ceil(textRect.size.width)tương ứng để có được chiều cao / chiều rộng thực.
Florian Friedrich

20
BOLIVIASize là cái quái gì vậy?
JRam13

36

Vì chúng tôi không thể sử dụng sizeWithAttribution cho tất cả iOS lớn hơn 4.3, chúng tôi phải viết mã có điều kiện cho 7.0 và iOS trước đó.

1) Giải pháp 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) Giải pháp 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];

Giải pháp đầu tiên đôi khi không trả về giá trị phù hợp của chiều cao. Vì vậy, sử dụng một giải pháp khác. Nó sẽ hoạt động hoàn hảo.

Tùy chọn thứ hai khá tốt và hoạt động trơn tru trong tất cả iOS mà không cần mã có điều kiện.


1
Tại sao 230, 999? Bạn lấy số ở đâu>
user4951

1
Số 230 có thể là bất kỳ số nào. Nó đại diện cho chiều rộng bạn muốn cho nhãn của bạn. 9999 tôi muốn thay thế bằng INFINITY hoặc MAXFLOAT.
Florian Friedrich

Giải pháp thứ hai là làm việc như một lá bùa. Cảm ơn Nirav.
Jim

1
"[AppHandlers zHandler]" báo lỗi .. "Số nhận dạng không khai báo". Làm thế nào để giải quyết điều đó?
Dimple

9

Đây là giải pháp đơn giản:

Yêu cầu:

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

Hiện tại, constrainedToSizeusage:lineBreakMode:việc sử dụng không được chấp nhận trong iOS 7.0 :

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

Bây giờ việc sử dụng trong phiên bản iOS 7.0 lớn hơn sẽ là:

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

Dưới đây là hai phương pháp đơn giản sẽ thay thế hai phương pháp không dùng nữa.

Và đây là các tài liệu tham khảo có liên quan:

Nếu bạn đang sử dụng NSLineBreakByWordWrapping, bạn không cần chỉ định NSPar ĐoạnStyle, vì đó là mặc định: https://developer.apple.com/l Library / mac / document / Cocoa / Reference / AplplicationKit html # // apple_Vf / const / clm / NSPar ĐoạnStyle / defaultPar ĐoạnStyle

Bạn phải lấy trần của kích thước, để phù hợp với kết quả của các phương pháp không dùng nữa. 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

Trong hầu hết các trường hợp, tôi đã sử dụng phương thức sizeWithFont: ràng buộcToSize: lineBreakMode: để ước tính kích thước tối thiểu cho một UILabel để chứa văn bản của nó (đặc biệt là khi nhãn phải được đặt bên trong UITableViewCell) ...

... Nếu đây chính xác là tình huống của bạn, bạn có thể mô phỏng theo phương pháp:

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

Hy vọng điều này có thể giúp đỡ.


5
Tài liệu của Apple nói rằng bạn không nên gọi phương thức này trực tiếp.
Barlow Tucker

Không được đề cập trong tài liệu SDK iOS 7 ít nhất.
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
Chào mừng bạn đến với StackOverFlow. Đừng đăng một câu trả lời tương tự một lần nữa. Nếu bạn cần thêm một cái gì đó vào câu trả lời, hãy bình luận hoặc chỉnh sửa câu trả lời.
Ramaraj T

ok..Tôi sẽ cân nhắc điều đó vào lần tới. Cảm ơn vì lời khuyên của bạn.
dùng3575114

2

[Câu trả lời được chấp nhận hoạt động độc đáo trong một thể loại. Tôi đang ghi đè tên phương thức không dùng nữa. Đây có phải là một ý tưởng tốt? Có vẻ như không hoạt động mà không có khiếu nại trong Xcode 6.x]

Điều này hoạt động nếu Mục tiêu triển khai của bạn là 7.0 hoặc cao hơn. Thể loại là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;

từ hai câu trả lời 1 + 2

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.