2013-09-23 59 views
5

Nhiều phương pháp tôi đã sử dụng để xác định bố cục của chuỗi in để tạo tài liệu pdf phức tạp đã không được chấp nhận trong iOS7. Tài liệu các cuộc gọi ra cùng một phương pháp sử dụng để thay thế cho tất cả các phương pháp sizeWithFont được chấp nhận:Thay thế cho sizeWithFont: ForWidth: lineBreakMode:

boundingRectWithSize:options:attributes: 

Đó là tốt cho sizeWithFont:ConstrainedTosize:lineBreakMode nhưng những gì nếu tôi muốn chuỗi của tôi trên chỉ có một dòng? Tôi không biết phải sử dụng cái gì cho chiều cao tối đa nên tôi không có giao tiếp để chuyển thành giá trị cho tham số đầu tiên.

Dưới đây là những gì tôi có khi giới hạn ở một kích thước nhất định.

CGFloat maxHeightAllowable = _maxHeight; 
CGSize issueTitleMaxSize = CGSizeMake(_issueListTitleColWidth - (kColumnMargin *2), maxHeightAllowable); 
NSDictionary *issueTitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:_bodyFont, NSFontAttributeName, nil]; 
CGRect issueTitleRect = CGRectIntegral([issueTitleText boundingRectWithSize:issueTitleMaxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:issueTitleAttributes context:nil]); 
CGSize issueTitleSize = issueTitleRect.size; 

Làm cách nào để sử dụng cùng phương pháp này nếu tôi không biết maxHeight, hoặc thực sự, chiều cao cho một dòng chính xác là những gì tôi đang cố gắng tìm ra?

Tôi thấy lý do tại sao họ đang thúc đẩy khả năng tương thích cho các chuỗi NSAttributed và bố cục tự động nhưng tại sao không dùng nữa? Trường hợp thay thế, trong trường hợp của tôi, bây giờ phải mất 4 hoặc 5 bước mà nó đã từng là 1 hoặc 2.

Sử dụng dòng Thuộc tính ánh sáng của phông chữ, theo đề xuất của Mr T, tôi đã thực hiện các phương pháp này trong một danh mục đơn giản hóa rất nhiều thay thế.

#import "NSString+SizingForPDF.h" 

@implementation NSString (SizingForPDF) 

-(CGSize)integralSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)maxSize 
{ 
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; 
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attributes context:nil]); 
    return rect.size; 
} 

-(CGSize)integralSizeWithFont:(UIFont *)font maxWidth:(CGFloat)maxWidth numberOfLines:(NSInteger)lines 
{ 
    if (lines == 0) { 
     lines = 1; 
    } 
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; 
    CGFloat height = font.lineHeight * lines; 
    CGSize maxsize = CGSizeMake(maxWidth, height); 
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading attributes:attributes context:nil]); 
    return rect.size; 
} 

@end 

Trả lời

15

Nếu bạn chỉ tìm chiều cao của một dòng, bạn có thể sử dụng thuộc tính lineHeight của phông chữ không? Tôi sử dụng nó để thiết lập chiều cao của các nhãn của tôi hoặc dự đoán chính xác chiều cao của các phần tử mà không có bất kỳ vấn đề nào. Tôi không chắc chắn nếu tài liệu pdf khác nhau về vấn đề này. Ngoài ra, tôi tin rằng những chức năng đó không được chấp nhận vì hàng loạt chức năng NSString + UIKit (sizeWithFont:..., v.v.) được dựa trên thư viện UIStringDrawing, không phải là chủ đề an toàn. Nếu bạn cố gắng chạy chúng không nằm trên luồng chính (giống như bất kỳ chức năng UIKit nào khác), bạn sẽ nhận được các hành vi không thể đoán trước. Đặc biệt, nếu bạn chạy chức năng trên nhiều luồng cùng một lúc, nó có thể sẽ làm hỏng ứng dụng của bạn. Đây là lý do tại sao trong iOS 6, họ đã giới thiệu phương thức boundingRectWithSize:... cho NSAttributedStrings. Điều này được xây dựng trên các thư viện NSStringDrawing và là luồng an toàn.

Trên ghi chú đó, nếu bạn chỉ hỗ trợ iOS 6 và iOS 7, thì tôi chắc chắn sẽ thay đổi tất cả số sizeWithFont:... của NSString của bạn thành số boundingRectWithSize của NSAttributeString. Nó sẽ giúp bạn tiết kiệm rất nhiều đau đầu nếu bạn tình cờ có một trường hợp góc đa luồng lạ! Đây là cách tôi chuyển NSString của sizeWithFont:constrainedToSize::

gì đã từng là:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
CGSize size = [text sizeWithFont:font 
       constrainedToSize:(CGSize){width, CGFLOAT_MAX}]; 

Có thể dễ dàng thay thế bằng:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
NSAttributedString *attributedText = 
    [[NSAttributedString alloc] 
     initWithString:text 
     attributes:@ 
     { 
      NSFontAttributeName: font 
     }]; 
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} 
              options:NSStringDrawingUsesLineFragmentOrigin 
              context:nil]; 
CGSize size = rect.size; 

Xin lưu ý các tài liệu đề cập đến:

Trong iOS 7 và sau đó, phương thức này trả về kích thước phân đoạn (trong kích thước thành phần của lợi nhuận ed CGRect); để sử dụng kích thước trả về kích thước lượt xem, bạn phải sử dụng tăng giá trị của nó lên số nguyên cao nhất gần nhất bằng hàm ceil.

Vì vậy, để kéo ra chiều cao tính toán hoặc chiều rộng được sử dụng cho kích thước quan điểm, tôi sẽ sử dụng:

CGFloat height = ceilf(size.height); 
CGFloat width = ceilf(size.width); 
+0

phương pháp của bạn là khá nhiều giống như tôi, chỉ có tôi sử dụng vĩ mô CGRectIntegral để kiểm soát các giá trị cho số nguyên. Tôi không bao giờ nghĩ đến việc xem font cho chiều cao dòng. Đó là câu trả lời cho tôi. Tôi đã sử dụng nó để tạo một vài phương pháp mới trong một danh mục dễ dàng thay thế mã cũ của tôi. –

+1

LineBreakMode được thay thế bằng thuộc tính NSParagraphStyle có thể được thêm vào từ điển thuộc tính. Xem http://stackoverflow.com/a/26894770/338468 để biết ví dụ chi tiết về cách thực hiện việc này. –