2009-07-30 35 views
5

Tôi đang cố gắng đo kích thước hình ảnh của một NSString có tính đến số lượng các dòng tôi có thể hiển thị. Tuy nhiên, sizeWithFont không đưa vào tài khoản numberOfLines tài sản? Vì vậy, thuật toán bố cục của tôi đặt mọi thứ thấp hơn chúng thực sự cần.Kích thước iPhone UILabelWithFont:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
/// the follow code ignores numberOfLines and just tells me the size of the whole block. 
// I'd like it to be aware of numberOfLines 
// 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX) 
     lineBreakMode:UILineBreakModeWordWrap]; 

Có ai biết cách thực hiện việc này bằng SDK iPhone không?

Trả lời

12

Thay vì CGFLOAT_MAX cho chiều cao tối đa tính văn bản của bạn, hãy thử nhận được kích thước của một dòng với điều này:

[_price.text sizeWithFont:_price.font].height 

và sau đó nhân rằng bằng cách tối đa # của dòng bạn muốn, sau đó cắm đó vào chiều cao của kích thước bạn đang tự ràng buộc bản thân. Có thể nó sẽ giống như sau:

_price = [[UILabel alloc] init]; 
_price.text = myPriceValue; 
_price.lineBreakMode = UILineBreakModeWordWrap; 
_price.numberOfLines = 3; 
_price.backgroundColor = [UIColor clearColor]; 
_price.textColor = TTSTYLEVAR(colorPrice); 
CGFloat lineHeight = [_price.text sizeWithFont:_price.font].height; 
CGSize priceSize = [_price.text sizeWithFont:_price.font 
     constrainedToSize:CGSizeMake(maxWidth, lineHeight * _price.numberOfLines) 
     lineBreakMode:UILineBreakModeWordWrap]; 

Không sử dụng nếu bạn đã đặt số dòng thành 0 là chiều cao tối đa của bạn sẽ là 0 trong trường hợp đó; bạn nên sử dụng CGFLOAT_MAX sau đó.

+2

sizeWithFont không được dùng trong iOS7 và boundingRectWithSize nên được sử dụng thay thế. –

-1

Tất nhiên nó không tính đến điều đó, vì không có gì được gọi hoặc thông qua có thông tin đó. Bạn đang làm việc nghiêm túc với các chuỗi, kích cỡ và phông chữ. Đó là nhãn có số dòng trong đó.

Tôi không chắc chính xác vấn đề của bạn là gì; bạn đang nhận được một kích thước quá cao hoặc quá ngắn, hoặc những gì? Bạn có thể tìm ra số dòng văn bản bằng cách chia chiều cao của kết quả theo chiều cao của phông chữ, đó là giá trị của ascender cộng với dấu gạch ngang, tôi tin.

+0

Thực ra, sizeWithFont: constainedToSize: lineBreakMode tính đến hộp giới hạn và gói từ. Lưu ý rằng sizeWithFont: forWidth: lineBreakMode KHÔNG hoạt động với nhiều dòng. –

0

Thay vì cố gắng làm điều đó trong một cuộc gọi, hãy làm một cái gì đó như thế này (tha thứ những giả, đó là cuối):

NSString *s = _price.text; 
UIFont *font = _price.font; 
CGFloat fontSize = font.pointSize; 

while (TRUE) 
{ 
    CGSize priceSize = [s sizeWithFont: font constrainedToSize: 
     CGSizeMake(maxWidth, fontSize) lineBreakMode: UILineBreakModeWordWrap]; 

    if (/* priceSize is satisfactory */) 
    { 
     break; // Make sure this exits, eventually!!! 
    } 
    fontSize -= 1.0; // or a smaller decrement if you like 
    font = // new, smaller font 

} 
0

Câu trả lời chính xác được, tất nhiên, bạn cần phải thiết lập numberOfLines 0, điều này sẽ khiến cho khung tính toán kết quả với nhiều dòng cần thiết. Xem thêm this question.

+0

Không, số dòng là 0 là các dòng vô hạn. nhưng tôi muốn chiều cao của 3 dòng – CVertex

+0

Ah, tôi hiểu rồi. Tôi hiểu lầm câu hỏi. –

5

Sử dụng kích thước của UILabelToFit thay vì sizeWithFont: để bố cục UILabel nhiều dòng, vì sizeWithFont: sẽ cắt ngắn chuỗi (xem tài liệu của apple). Các mã sau đây làm giảm kích thước phông chữ của một nhãn cho đến khi các văn bản phù hợp vào một kích thước quy định ... nhiều dòng văn bản sẽ được sử dụng ngay sau khi họ phù hợp với chiều cao quy định:

-(void)setFontSizeOfMultiLineLabel: (UILabel*)label 
     toFitSize: (CGSize) size 
     forMaxFontSize: (CGFloat) maxFontSize 
     andMinFontSize: (CGFloat) minFontSize 
     startCharacterWrapAtSize: (CGFloat)characterWrapSize{ 

CGRect constraintSize = CGRectMake(0, 0, size.width, 0); 
label.frame = constraintSize; 
label.lineBreakMode = UILineBreakModeWordWrap; 
label.numberOfLines = 0; // allow any number of lines 

for (int i = maxFontSize; i > minFontSize; i--) { 

    if((i < characterWrapSize) && (label.lineBreakMode == UILineBreakModeWordWrap)){ 
     // start over again with lineBreakeMode set to character wrap 
     i = maxFontSize; 
     label.lineBreakMode = UILineBreakModeCharacterWrap; 
    } 

    label.font = [label.font fontWithSize:i]; 
    [label sizeToFit]; 
    if(label.frame.size.height < size.height){ 
     break; 
    }  
    label.frame = constraintSize; 
    } 
} 

Gọi này với một nhãn có văn bản và phông chữ yêu thích của bạn:

UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero]; 
label.backgroundColor = [UIColor clearColor]; 
label.textColor = [UIColor whiteColor]; 
label.text = text; 
label.font = [UIFont fontWithName: @"Helvetica" size: 16]; 
[self setFontSizeOfMultiLineLabel: label toFitSize: CGSizeMake(200, 44) forMaxFontSize: 16 andMinFontSize: 8 startCharacterWrapAtSize: 11]; 

Tham số startCharacterWrapAtSize cho phép bạn chọn sử dụng characterWrap bắt đầu từ kích thước phông chữ cho. Điều này sẽ tiết kiệm không gian trong trường hợp wordWrap sẽ sử dụng phông chữ thực sự nhỏ.

chỉnh sửa: bugfix

+0

Điều này cũng sẽ hoạt động tốt như một danh mục trên 'UILabel' –

Các vấn đề liên quan