是的,但不在 UILabel 中,也不使用 sizeWithFont:。
我最近与 Apple Developer Support 合作,显然 sizeWithFont: 实际上是一个近似值。当您的文本 (1) 跨越多行并且 (2) 包含非拉丁字符(即中文、阿拉伯语)时,它会变得不那么准确,这两者都会导致 sizeWithFont: 无法捕获行间距变化。因此,如果您想要 100% 的准确率,请不要依赖此方法。
您可以做以下两件事:
(1) 使用不可编辑的 UITextView 代替 UILabel。这将支持 UITextInput 协议方法firstRectForRange:,您可以使用它来获取所需字符的矩形。你可以使用这样的方法:
- (CGRect)rectOfCharacterAtIndex:(NSUInteger)characterIndex inTextView:(UITextView *)textView
{
// set the beginning position to the index of the character
UITextPosition *beginningPosition = [textView positionFromPosition:textView.beginningOfDocument offset:characterIndex];
// set the end position to the index of the character plus 1
UITextPosition *endPosition = [textView positionFromPosition:beginningPosition offset:1];
// get the text range between these two positions
UITextRange *characterTextRange = [textView textRangeFromPosition:beginningPosition toPosition:endPosition]];
// get the rect of the character
CGRect rectOfCharacter = [textView firstRectForRange:characterTextRange];
// return the rect, converted from the text input view (unless you want it to be relative the text input view)
return [textView convertRect:rectOfCharacter fromView:textView.textInputView];
}
要使用它(假设屏幕上已经有一个名为 myTextView 的 UITextView),您可以这样做:
myTextView.text = @"Hello!";
CGRect rectOfOCharacter = [self rectOfCharacterAtIndex:4 inTextView:myTextView];
// do whatever you need with rectOfOCharacter
仅使用此方法确定ONE字符的矩形。原因是在换行的情况下, firstRectForRange: 只返回第一行的矩形,在换行之前。
另外,如果您要经常使用它,请考虑将上述方法添加为 UITextView 类别。不要忘记添加错误处理!
您可以通过阅读适用于 iOS 的文本、Web 和编辑编程指南来了解有关 firstRectForRange: 如何“在后台”工作的更多信息。
(2) 通过继承 UIView 并使用 Core Text 渲染字符串来创建自己的 UILabel。由于您正在进行渲染,因此您将能够获得字符的位置。这种方法需要做很多工作,只有在你真的需要它时才值得(当然,我不知道你的应用程序的其他需求)。如果您不确定这将如何工作,我建议使用第一种方法。