gpt4 book ai didi

objective-c - 如何知道 NSString 是否适合 UILabel 以及最后一个适合的字符串的索引?

转载 作者:可可西里 更新时间:2023-11-01 04:23:57 25 4
gpt4 key购买 nike

我有 4 行具有精确框架和字体的 UILabel。

我需要知道这个字符串是否适合标签,以及最后一个适合的字符的索引是什么。

最佳答案

答案的核心在 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];
}

也许此处使用的字符集不太正确(例如,您是否应该包括连字符),但如果您不需要这样做,它可能非常接近并且比逐个字符更有效。

关于objective-c - 如何知道 NSString 是否适合 UILabel 以及最后一个适合的字符串的索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11155787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com