我正在尝试确定UILabel中角色的准确位置,比如说:
(UILabel *)label.text = @“你好!”;
我想确定'o'的位置。我认为我可以使用sizeWithFont将所有前面的字符(或整个前面的字符串)的宽度相加。我得到的宽度值比它应该大约10%。将各个字母的宽度相加(即[@“H”sizeWithFont ...] + [@“e”sizeWithFont ...] + l ... + l ...)比[@“Hell”sizeWithFont积累更多错误...]。
有没有办法准确确定字符串中单个字形的位置?
非常感谢。
答案 0 :(得分:4)
是的,但不是在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 字符的rect。这样做的原因是,如果换行,firstRectForRange:仅在中断前的第一行返回rect。
另外,如果您需要大量使用它,请考虑将上述方法添加为UITextView类别。不要忘记添加错误处理!
通过阅读Text, Web, and Editing Programming Guide for iOS,您可以了解有关firstRectForRange:如何在幕后工作的更多信息。
(2)通过继承UIView并使用Core Text来渲染字符串来创建自己的UILabel。由于您正在进行渲染,因此您将能够获得角色的位置。这种方法是很多工作,只有你真的需要它才有价值(当然,我不知道你的应用程序的其他需求)。如果您不确定这是如何工作的,我建议使用第一种方法。
答案 1 :(得分:0)
好的字体现在每天都很聪明,并且尊重角色在其前身角色中的位置。
以下是关于字母o
:
NSRange posRange = [hello rangeOfString:@"o"];
NSString *substring = [hello substringToIndex:posRange.location];
CGSize size = [substring sizeWithFont:[UIFont systemFontOfSize:14.0f]];
不能对包含字母o
的字符串执行相同的操作,并减去字符串中找不到字母o
的大小。
这应该给出一个很好的开头位置的字母和大小。
答案 2 :(得分:0)
NSMutableAttributedString *titleText2 = [[NSMutableAttributedString alloc] initWithString:strHello];
NSRange posRange = [hello rangeOfString:@"o"];
[titleText2 addAttributes:[NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:14.0f] forKey:NSFontAttributeName] range:NameRange];
并使用此属性字符串
设置textView