如果突出显示的单词是一行的第一个,则 textView 中的 NSBackgroundColorAttributeName 不考虑范围
NSBackgroundColorAttributeName in textView doesn't respect range if highlighted word is first of a line
我正在实施 "search in chat" 功能,我希望搜索到的词在消息中突出显示。如标题所述,问题是如果单词是一行的第一行(长消息显然 multi-line),则整行而不是单个单词被突出显示。
调试的时候,我也试过用下划线代替backgroundcolor,下划线是正确的。我不知道问题出在哪里。
我的应用程序的聊天是基于 JSQMessagesViewController 所以我认为问题可能出在这里。
[attributedString addAttribute:NSBackgroundColorAttributeName
value:backColor
range:wordRange];
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:@(NSUnderlineStyleSingle)
range:wordRange];
cell.textView.attributedText = attributedString;
我没有post计算范围的代码,因为范围是正确的;事实上,如果我在调试中查看 attributedString 的预览(我将其分配给 cell.textView.attributedText),我可以看到只有单词被突出显示,而不是所有字符串。
这是一个例子:
似乎是系统框架中的错误,所以最好的办法可能是再添加一行代码,将背景颜色设置回 "unchanged",紧接在应该更改背景的最后一个字符之后。
祝你好运!
看了official documentation后,我发现有3个方法做类似的动作。
因此,可能还有其他方法,例如 setAttributes:range:,可能会解决您的问题。
[attributedString setAttributes:@{NSBackgroundColorAttributeName : backColor}
range:wordRange];
cell.textView.attributedText = attributedString;
另外,Whosebug上也有类似的问题。也许 this answer 会对你有所帮助。
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:(id)backColor.CGColor
forKey:(id)kCTBackgroundColorAttributeName];
[attributedString addAttributes:stringAttributes
range:wordRange];
cell.textView.attributedText = attributedString;
更新#1
刚刚找到 Attributed String Programming Guide.
它说,
All of the methods for changing a mutable attributed string properly update the mapping between characters and attributes, but after a change some inconsistencies can develop.
或许,以上原因导致了您的问题...
我不确定它是否有帮助,但有一个例子:
NSMutableAttributedString *string; // assume string exists
NSRange selectedRange; // assume this is set
NSURL *linkURL = [NSURL URLWithString:@"http://www.apple.com/"];
[string beginEditing]; // ★★★ Apple uses beginEditing ★★★
[string addAttribute:NSLinkAttributeName
value:linkURL
range:selectedRange];
[string addAttribute:NSForegroundColorAttributeName
value:[NSColor blueColor]
range:selectedRange];
[string addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSSingleUnderlineStyle]
range:selectedRange];
[string endEditing]; // ★★★ and endEditing ★★★
我正在实施 "search in chat" 功能,我希望搜索到的词在消息中突出显示。如标题所述,问题是如果单词是一行的第一行(长消息显然 multi-line),则整行而不是单个单词被突出显示。
调试的时候,我也试过用下划线代替backgroundcolor,下划线是正确的。我不知道问题出在哪里。 我的应用程序的聊天是基于 JSQMessagesViewController 所以我认为问题可能出在这里。
[attributedString addAttribute:NSBackgroundColorAttributeName
value:backColor
range:wordRange];
[attributedString addAttribute:NSUnderlineStyleAttributeName
value:@(NSUnderlineStyleSingle)
range:wordRange];
cell.textView.attributedText = attributedString;
我没有post计算范围的代码,因为范围是正确的;事实上,如果我在调试中查看 attributedString 的预览(我将其分配给 cell.textView.attributedText),我可以看到只有单词被突出显示,而不是所有字符串。
这是一个例子:
似乎是系统框架中的错误,所以最好的办法可能是再添加一行代码,将背景颜色设置回 "unchanged",紧接在应该更改背景的最后一个字符之后。 祝你好运!
看了official documentation后,我发现有3个方法做类似的动作。
因此,可能还有其他方法,例如 setAttributes:range:,可能会解决您的问题。
[attributedString setAttributes:@{NSBackgroundColorAttributeName : backColor}
range:wordRange];
cell.textView.attributedText = attributedString;
另外,Whosebug上也有类似的问题。也许 this answer 会对你有所帮助。
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:(id)backColor.CGColor
forKey:(id)kCTBackgroundColorAttributeName];
[attributedString addAttributes:stringAttributes
range:wordRange];
cell.textView.attributedText = attributedString;
更新#1
刚刚找到 Attributed String Programming Guide.
它说,
All of the methods for changing a mutable attributed string properly update the mapping between characters and attributes, but after a change some inconsistencies can develop.
或许,以上原因导致了您的问题... 我不确定它是否有帮助,但有一个例子:
NSMutableAttributedString *string; // assume string exists
NSRange selectedRange; // assume this is set
NSURL *linkURL = [NSURL URLWithString:@"http://www.apple.com/"];
[string beginEditing]; // ★★★ Apple uses beginEditing ★★★
[string addAttribute:NSLinkAttributeName
value:linkURL
range:selectedRange];
[string addAttribute:NSForegroundColorAttributeName
value:[NSColor blueColor]
range:selectedRange];
[string addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSSingleUnderlineStyle]
range:selectedRange];
[string endEditing]; // ★★★ and endEditing ★★★