layoutManager boundingRectForGlyphRange:inTextContainer:不适用于所有string

我有一个像string鸣叫UILabel,包括提及其他用户。

Hey @stephen and @frank and @Jason1. 

我试图让每个提及可点击,所以我可以加载该用户的configuration文件。 我发现从另一个SOpost( 我如何find一个UILabel中的文本的子string的CGRect? )一些代码,我可以用来定位每个提到的string的位置。 但是,对于post中的最后或最后两个提及,通常不起作用。

SOpost的方法(稍作修改):

 - (CGRect)boundingRectForCharacterRange:(NSRange)range { NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.myLabel.attributedText]; NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedString]; NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init]; [textStorage addLayoutManager:layoutManager]; NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:self.myLabel.bounds.size]; textContainer.lineFragmentPadding = 0; [layoutManager addTextContainer:textContainer]; NSRange glyphRange; // Convert the range for glyphs. [layoutManager characterRangeForGlyphRange:range actualGlyphRange:&glyphRange]; return [layoutManager boundingRectForGlyphRange:glyphRange inTextContainer:textContainer]; } 

然后,在touchesEnded: ,我循环遍历每个提及,获取主string中的范围,并检查触摸是否在CGRect中。

 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = touches.allObjects[0]; for (NSString *mention in self.mentions) { NSRange range = [self.postText rangeOfString:mention options:NSCaseInsensitiveSearch]; CGRect rect = [self boundingRectForCharacterRange:range]; NSLog(@"rect for %@ is %@", mention, NSStringFromCGRect(rect)); } } // Output from above rect for @stephen is {{33.388, 0}, {72.471001, 20.553001}} rect for @frank is {{143.021, 0}, {49.809998, 20.553001}} rect for @Jason1 is {{0, 0}, {0, 0}} 

而这个工程大部分时间都很好,但是@Jason1没有得到匹配。 我已经改变了名字的顺序,它总是最后一个。 我的标签没有换行,但有时还会匹配第二行和第三行的名称。 有没有设置或我失踪的东西? 我试过改变标签的大小和字体,但没有运气。 我在这里真正的损失。

对此的修复不是在初始化NSTextContainer时设置高度约束。 使用一个非常大的数字。

 NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(self.myLabel.bounds.size.width, CGFLOAT_MAX)];