Hạt nhân của câu trả lời nằm trong bài đăng được tham chiếu của Cupcake. Dù sao, bạn có thể sử dụng sizeWithFont:constrainedToSize:lineBreakMode:
để tìm ra kích thước của khung sẽ bằng một phông chữ cụ thể trong một nhãn có chiều rộng nhất định cho một từ cụ thể, ví dụ:
CGSize size = [string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:UILineBreakModeWordWrap];
Đặt sizeConstraint
bằng cùng chiều rộng của nhãn, nhưng đặt chiều cao lớn hơn. Nếu kết quả size.height
lớn hơn UILabel của bạn, thì chuỗi của bạn quá dài. Về mặt lý thuyết, bạn có thể xóa ký tự/từ cuối cùng và thử lại và lặp lại cho đến khi nó khớp.
Nếu bạn nghĩ rằng các chuỗi có thể rất dài, bạn có thể muốn đi theo cách khác, bắt đầu bằng một phần ngắn của chuỗi và tiếp tục thêm ký tự cho đến khi quá lớn và sau đó bạn biết ký tự cuối cùng.
Dù bằng cách nào, tính toán lặp lại này của kích thước có thể là hoạt động khá cpu chuyên sâu, vì vậy hãy cẩn thận.
Cập nhật:
Dưới đây là một thuật toán trả về chiều dài của NSString
có thể phù hợp với UILabel
trong câu hỏi bằng cách sử dụng phông chữ mặc định (nhưng bỏ qua kích thước phông chữ tối thiểu):
- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
UIFont *font = label.font;
UILineBreakMode mode = label.lineBreakMode;
CGFloat labelWidth = label.frame.size.width;
CGFloat labelHeight = label.frame.size.height;
CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);
if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
{
NSString *adjustedString;
for (NSUInteger i = 1; i < [string length]; i++)
{
adjustedString = [string substringToIndex:i];
if ([adjustedString sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
return i - 1;
}
}
return [string length];
}
Bạn có thể có thể làm cho điều này hiệu quả hơn nếu bạn, ví dụ, kiểm tra xem chế độ ngắt từ, nhảy tới từ phân cách tiếp theo và sau đó gọi sizeWithFont
, nhưng đối với UILabel
nhỏ, điều này có thể là đủ. Nếu bạn muốn tận dụng luận lý word-wrap để giảm thiểu số lần bạn gọi sizeWithFont
, bạn có thể có một cái gì đó như:
- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
UIFont *font = label.font;
UILineBreakMode mode = label.lineBreakMode;
CGFloat labelWidth = label.frame.size.width;
CGFloat labelHeight = label.frame.size.height;
CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);
if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
{
NSUInteger index = 0;
NSUInteger prev;
NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
do
{
prev = index;
if (mode == UILineBreakModeCharacterWrap)
index++;
else
index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
}
while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight);
return prev;
}
return [string length];
}
Có lẽ bộ ký tự sử dụng ở đây là không hoàn toàn đúng (bạn nên bao gồm dấu gạch nối, cho Ví dụ), nhưng nó có thể khá gần và hiệu quả hơn nhiều so với làm nhân vật theo nhân vật, nếu bạn không cần phải làm điều đó.
Câu hỏi này sẽ giúp bạn: http://stackoverflow.com/questions/6422742/how-to-know-the-length-of-nsstring-that-fits-a-uilabel-with-fixed-size –
Tôi đã xem xét điều này trước nhưng nó không giúp được –
câu trả lời @Cupcake được đăng ở đây sẽ giúp bạn –