我有4行UILabel,具有精确的框架和字体。
我需要知道这个字符串是否适合标签,以及最后一个字符的索引是什么。
答案 0 :(得分:9)
答案的核心是Cupcake的引用帖子。无论如何,您可以使用sizeWithFont:constrainedToSize:lineBreakMode:
来确定给定特定自动换行的给定宽度的标签中的特定字体的帧大小。
CGSize size = [string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:UILineBreakModeWordWrap];
将sizeConstraint
设置为与标签相同的宽度,但将高度设置为更大。如果生成的size.height
大于您的UILabel,那么您的字符串太长。从理论上讲,你可以删除最后一个字符/单词,然后再试一次,直到它适合。
如果您认为字符串可能很长,您可能想要另一种方式,从字符串的一小部分开始并继续添加字符直到它太大,然后您知道最后一个字符。
无论哪种方式,这个迭代计算的大小都可以进行cpu密集操作,所以要小心。
<强>更新强>
这是一种算法,它使用默认字体(但忽略最小字体大小)返回可以容纳到NSString
中的UILabel
的长度:
- (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];
}
例如,如果您检查了分词模式,跳转到下一个单词分隔符然后调用sizeWithFont
,那么您可能会提高效率,但对于小UILabel
s,这可能就足够了。如果您想利用自动换行逻辑来最小化调用sizeWithFont
的次数,您可能会有以下内容:
- (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];
}
这里使用的字符集可能不太正确(例如,如果你包括连字符),但它可能非常接近并且比逐字符更有效,如果你不需要这样做的话。 / p>