这是 使用NSTextContainer和NSLayoutManager来用CALayer突出显示文本 的延续。我在获取每个行片段范围的正确矩形方面遇到了麻烦。请注意保留原有的HTML标签,不需要解释文本内容。
这是我的当前尝试。我基本上使用enumerateLineFragmentsForGlyphRange:usingBlock:循环遍历每一行。然后我使用enumerateEnclosingRectsForGlyphRange:withinSelectedGlyphRange:usingBlock:确保当前行文本范围与该行范围匹配,并具有相同的Y坐标。有时它有效,有时不起作用。
似乎如果搜索文本靠近回车键,它会将高亮显示偏移得很远(y坐标)。
在这个截图中,“返回生成字符的范围”应该被突出显示。
似乎如果文本不靠近回车或空格,这将正常工作:
如果周围没有空格,它会正确地工作。
我错过了什么吗?
更新:
我已经缩小了问题的范围,我相信enumerateLineFragmentsForGlyphRange:usingBlock:正在跳过具有返回值的行。
NSString* searchString = @"Returns the range of characters that generated";
NSRange match = [[[self textView]text]rangeOfString:searchString];
NSRange matchingGlyphRange = [manager glyphRangeForCharacterRange:match actualCharacterRange:NULL];
[manager enumerateLineFragmentsForGlyphRange:matchingGlyphRange usingBlock:
^(CGRect lineRect, CGRect usedRect, NSTextContainer *textContainer, NSRange lineRange, BOOL *stop) {
NSRange currentRange = NSIntersectionRange(lineRange, matchingGlyphRange);
[manager enumerateEnclosingRectsForGlyphRange:currentRange withinSelectedGlyphRange:NSMakeRange(NSNotFound, 0) inTextContainer:textContainer usingBlock:
^(CGRect rect, BOOL* stop) {
if (usedRect.origin.y == rect.origin.y && NSLocationInRange(currentRange.location, lineRange)) {
CGRect theRect = [manager boundingRectForGlyphRange:currentRange inTextContainer:textContainer];
CALayer* roundRect = [CALayer layer];
[roundRect setFrame:theRect];
[roundRect setBounds:theRect];
[roundRect setCornerRadius:5.0f];
[roundRect setBackgroundColor:[[UIColor blueColor]CGColor]];
[roundRect setOpacity:0.2f];
[roundRect setBorderColor:[[UIColor blackColor]CGColor]];
[roundRect setBorderWidth:3.0f];
[roundRect setShadowColor:[[UIColor blackColor]CGColor]];
[roundRect setShadowOffset:CGSizeMake(20.0f, 20.0f)];
[roundRect setShadowOpacity:1.0f];
[roundRect setShadowRadius:10.0f];
[[[self textView]layer]addSublayer:roundRect];
*stop = YES;
}
}];
}];
这是我的当前尝试。我基本上使用enumerateLineFragmentsForGlyphRange:usingBlock:循环遍历每一行。然后我使用enumerateEnclosingRectsForGlyphRange:withinSelectedGlyphRange:usingBlock:确保当前行文本范围与该行范围匹配,并具有相同的Y坐标。有时它有效,有时不起作用。
似乎如果搜索文本靠近回车键,它会将高亮显示偏移得很远(y坐标)。
在这个截图中,“返回生成字符的范围”应该被突出显示。
似乎如果文本不靠近回车或空格,这将正常工作:
如果周围没有空格,它会正确地工作。
我错过了什么吗?
更新:
我已经缩小了问题的范围,我相信enumerateLineFragmentsForGlyphRange:usingBlock:正在跳过具有返回值的行。