gpt4 book ai didi

objective-c - NSString constrainedToSize 方法?

转载 作者:塔克拉玛干 更新时间:2023-11-01 19:12:04 25 4
gpt4 key购买 nike

不要与返回 CGSizeNSString sizeWithFont 方法混淆,我正在寻找的是返回 NSString 的方法> 受限于某个 CGSize。我想要这样做的原因是当使用 Core Text 绘制文本时,我可以在字符串的末尾附加一个省略号 (...)。我知道 NSString 的 drawInRect 方法为我做了这个,但我使用的是 Core Text,并且 kCTLineBreakByTruncatingTail 截断了每行的末尾 而不是字符串的结尾。

this method that I found将字符串截断为特定的宽度,更改它以使其适用于CGSize 并不难,但该算法对于长字符串来说慢得令人难以置信,并且几乎无法使用。 (截断一个长字符串需要 10 多秒)。必须有一种更“计算机科学”/数学算法的方法来更快地做到这一点。有人敢于尝试提出更快的实现方法吗?

编辑:我已经设法将其转化为二进制算法:

-(NSString*)getStringByTruncatingToSize:(CGSize)size string:(NSString*)string withFont:(UIFont*)font
{
int min = 0, max = string.length, mid;
while (min < max) {
mid = (min+max)/2;

NSString *currentString = [string substringWithRange:NSMakeRange(min, mid - min)];
CGSize currentSize = [currentString sizeWithFont:font constrainedToSize:CGSizeMake(size.width, MAXFLOAT)];

if (currentSize.height < size.height){
min = mid + 1;
} else if (currentSize.height > size.height) {
max = mid - 1;
} else {
break;
}
}

NSMutableString *finalString = [[string substringWithRange:NSMakeRange(0, min)] mutableCopy];
if(finalString.length < self.length)
[finalString replaceCharactersInRange:NSMakeRange(finalString.length - 3, 3) withString:@"..."];

return finalString;
}

问题是,当有空余空间时,这有时会将字符串剪得太短。我认为这是最后一个条件发挥作用的地方。我如何确保它不会切断太多

最佳答案

好消息!有一种“计算机科学/数学方法”可以更快地做到这一点。

example you link to进行线性搜索:它只是从字符串末尾一次截取一个字符,直到足够短为止。因此,它所花费的时间量将与字符串的长度成线性比例关系,对于长字符串,它会非常慢,正如您所发现的那样。

但是,您可以轻松地对字符串应用二分搜索 技术。不是从最后开始并一次放下一个字符,而是从中间开始:

THIS IS THE STRING THAT YOU WANT TO TRUNCATE
^

您计算“THIS IS THE STRING THAT”的宽度。如果它太宽,则将测试点移动到左侧空间的中点。像这样:

THIS IS THE STRING THAT YOU WANT TO TRUNCATE
^ |

另一方面,如果它不够宽,则将测试点移动到另一半的中点:

THIS IS THE STRING THAT YOU WANT TO TRUNCATE
| ^

你重复这个直到你找到刚好在你的宽度限制之下的点。因为您每次都将搜索区域分成两半,所以您永远不需要计算超过 log2 N 次的宽度(其中 N 是字符串的长度),即使对于很长的字符串,宽度也不会增长得很快.

换句话说,如果您将输入字符串的长度加倍,那只是一个额外的宽度计算。

Wikipedia's binary search sample 开头, 这是一个例子。请注意,由于我们不是在寻找完全匹配(您想要最大的匹配),因此逻辑略有不同。

int binary_search(NSString *A, float max_width, int imin, int imax)
{
// continue searching while [imin,imax] is not empty
while (imax >= imin)
{
/* calculate the midpoint for roughly equal partition */
int imid = (imin + imax) / 2;

// determine which subarray to search
float width = ComputeWidthOfString([A substringToIndex:imid]);
if (width < max_width)
// change min index to search upper subarray
imin = imid + 1;
else if (width > max_width )
// change max index to search lower subarray
imax = imid - 1;
else
// exact match found at index imid
return imid;
}
// Normally, this is the "not found" case, but we're just looking for
// the best fit, so we return something here.
return imin;
}

您需要做一些数学运算或测试来确定底部的正确索引是什么,但它肯定是 iminimax,加一或减一。

关于objective-c - NSString constrainedToSize 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10690701/

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