Dưới đây là một O (log n) phương pháp với iOS 7 API. Chỉ được thử nghiệm bề ngoài, hãy bình luận nếu bạn tìm thấy bất kỳ lỗi nào.
- (NSRange)hp_visibleRange
{
NSString *text = self.text;
NSRange visibleRange = NSMakeRange(NSNotFound, 0);
const NSInteger max = text.length - 1;
if (max >= 0)
{
NSInteger next = max;
const CGSize labelSize = self.bounds.size;
const CGSize maxSize = CGSizeMake(labelSize.width, CGFLOAT_MAX);
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = self.lineBreakMode;
NSDictionary * attributes = @{NSFontAttributeName:self.font, NSParagraphStyleAttributeName:paragraphStyle};
NSInteger right;
NSInteger best = 0;
do
{
right = next;
NSRange range = NSMakeRange(0, right + 1);
NSString *substring = [text substringWithRange:range];
CGSize textSize = [substring boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
if (textSize.width <= labelSize.width && textSize.height <= labelSize.height)
{
visibleRange = range;
best = right;
next = right + (max - right)/2;
} else if (right > 0)
{
next = right - (right - best)/2;
}
} while (next != right);
}
return visibleRange;
}
Xin chào! Cảm ơn, người đàn ông. Nhưng có vẻ như với tôi rằng phương pháp này với vòng lặp quá nặng. Tôi muốn tìm một cái gì đó bản địa. – Evgeny
Tôi không biết cách làm điều này một cách tự nhiên. Trừ khi bạn sẽ được gọi mã này một số tiền rất lớn, tôi sẽ không tưởng tượng nó sẽ có bất kỳ tác động tiêu cực nào đến ứng dụng của bạn. Bạn có thể xem xét phân bổ và giải phóng tất cả các cá thể chuỗi nếu bạn thực sự lo lắng về việc sử dụng bộ nhớ. – Vertism
Tôi không lo lắng về bộ nhớ nhưng chỉ xử lý tải. Có vẻ như sizeWithFont nên thực sự nặng và tôi đã tự hỏi là có cách nào để có được, ví dụ, sự kiện UILabel khi nó cây trồng một số văn bản đi ... Đó là câu hỏi của tôi là về :-) Nhưng có vẻ như với tôi, rằng có không có giải pháp. Cách duy nhất là của bạn. – Evgeny