我有一个UILabel,带有类似字符串的推文,包括其他用户的提及.
I have a UILabel with a tweet like string, including mentions of other users.
Hey @stephen and @frank and @Jason1.我正在尝试使每个提及都可以点击,以便我可以加载该用户的个人资料.我从另一篇SO帖子中找到了一些代码(如何在UILabel中找到文本子字符串的CGRect?),我可以使用该CGRect来定位字符串中每个提及的位置.但是,对于帖子中的最后2条或最后2条提及,通常不起作用.
I am attempting to have each mention be tappable so I can load that user's profile. I found some code from another SO post (How do I locate the CGRect for a substring of text in a UILabel?) that I was able to use in order to locate the position of each mention in the string. However it usually doesn't work for the last or last 2 mentions in a post.
SO帖子中的方法(稍作修改):
The method from the SO post (slightly modified):
- (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:中,我遍历每个提及内容,获取主字符串中的范围,并检查触摸是否在该CGRect内部.
Then, in touchesEnded:, I loop over each mention, get the range in the main string, and check if the touch is inside that 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没有匹配.我已经切换了名称的顺序,并且始终是最后一个.我的标签确实会自动换行,但有时仍会与第二行和第三行上的名称匹配.是否有设置或我缺少的东西?我试过更改标签的大小和字体,但是没有运气.我在这里真是茫然.
And this works great most of the time, however @Jason1 does not get matched. I've switched the order of the names and it's always the last one. My label does wrap, but it still sometimes matches names on the 2nd and 3rd lines. Is there a setting or something I'm missing? I've tried changing the size and font of the labels but no luck. I'm at a real loss here.
推荐答案此问题的解决方法是在初始化NSTextContainer时不设置高度约束.改用非常大的数字.
The fix for this is not to set the height constraint when initializing the NSTextContainer. Use a very large number instead.
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:CGSizeMake(self.myLabel.bounds.size.width, CGFLOAT_MAX)];更多推荐
layoutManager boundingRectForGlyphRange:inTextContainer:不适用于所有字符串
发布评论