不要对返回NSString sizeWithFont
的{{1}}方法感到困惑,我正在寻找的方法是返回CGSize
约束到某个NSString
的方法。我想这样做的原因是,当使用CGSize
绘制文本时,我可以在字符串的末尾附加一个省略号(...)。我知道Core Text
方法为我做了这个,但是我使用的是NSString's drawInRect
,而Core Text
截断了每一行的结尾而不是字符串的结尾。
有this method that I found将字符串截断为某个宽度,并且要更改它以使其适用于kCTLineBreakByTruncatingTail
并不难,但算法令人难以置信长串慢,实际上无法使用。 (截断长字符串花了10多秒)。必须有更多的“计算机科学”/数学算法才能更快地完成这项工作。谁敢大胆尝试提出更快的实施?
编辑:我已设法将其转换为二进制算法:
CGSize
问题是,当它有足够的空间时,这有时会使弦太短。我认为这是最后一个条件发挥作用的地方。如何确保它不会切断太多?
答案 0 :(得分:6)
example you link to进行线性搜索:它只是从字符串末尾一次剁一个字符,直到它足够短。因此,它所花费的时间将与字符串的长度成线性比例,而对于长字符串,它将非常慢,正如您所发现的那样。
但是,您可以轻松地将二进制搜索技术应用于字符串。你不是从最后开始并一次放下一个角色,而是从中间开始:
THIS IS THE STRING THAT YOU WANT TO TRUNCATE
^
你计算“这就是这个字符串”的宽度。如果太宽,则将测试点移动到左侧空间的中点。像这样:
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;
}
您需要进行一些数学运算或测试以找出底部正确的索引,但它绝对是imin
或imax
,加上或减去一。