我正在尝试很好地显示NSTextView中突出显示的段落。现在,我是通过创建一个背景颜色的NSAttributedString来做到这一点的。这是一些简化的代码:
NSDictionary *attributes = @{NSBackgroundColorAttributeName:NSColor.greenColor};
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"Here is a single line of text with single spacing" attributes:attributes];
[textView.textStorage setAttributedString:attrString];
这种方法基本上有效,因为它产生突出显示的文本。
不幸的是,当存在多行时,除了行本身之外,高亮处覆盖行之间的垂直空间,导致丑陋。
有没有人知道在Cocoa中进行这种突出显示的方法?下面的图片基本上就是我要找的东西(忽略白框上的阴影):
我愿意使用CoreText,html或任何必要的东西来使事情变得更好。
答案 0 :(得分:3)
您需要继承NSLayoutManager并覆盖:
- (void)fillBackgroundRectArray:(const CGRect *)rectArray
count:(NSUInteger)rectCount
forCharacterRange:(NSRange)charRange
color:(UIColor *)color;
这是绘制背景颜色矩形的基本方法。
答案 1 :(得分:0)
试试这个: -
-(IBAction)chooseOnlylines:(id)sender
{
NSString *allTheText =[tv string];
NSArray *lines = [allTheText componentsSeparatedByString:@"\n"];
NSString *str=[[NSString alloc]init];
NSMutableAttributedString *attr;
BOOL isNext=YES;
[tv setString:@""];
for (str in lines)
{
attr=[[NSMutableAttributedString alloc]initWithString:str];
if ([str length] > 0)
{
NSRange range=NSMakeRange(0, [str length]);
[attr addAttribute:NSBackgroundColorAttributeName value:[NSColor greenColor] range:range];
[tv .textStorage appendAttributedString:attr];
isNext=YES;
}
else
{
NSString *str=@"\n";
NSAttributedString *attr=[[NSAttributedString alloc]initWithString:str];
[tv .textStorage appendAttributedString:attr];
isNext=NO;
}
if (isNext==YES)
{
NSString *str=@"\n";
NSAttributedString *attr=[[NSAttributedString alloc]initWithString:str];
[tv .textStorage appendAttributedString:attr];
}
}
}
答案 2 :(得分:0)
当用户点击该段落时,该段落需要突出显示。这就是我的实现方式,不要与 突出显示颜色 混淆,这是我为此创建的自定义NSAttributedString键。
extension NSAttributedString.Key {
public static let highlightColor = NSAttributedString.Key.init("highlightColor")
}
class ReaderLayoutManager: NSLayoutManager {
// MARK: - Draw Background
override func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
super.drawBackground(forGlyphRange: glyphsToShow, at: origin)
self.enumerateLineFragments(forGlyphRange: glyphsToShow) { (_, usedRect, _, range, _) in
guard let highlightColor = self.currentHighlightColor(range: range) else { return }
guard let context = UIGraphicsGetCurrentContext() else { return }
var lineRect = usedRect
lineRect.origin.y += 10
lineRect.size.height -= 2
context.saveGState()
let path = UIBezierPath(roundedRect: lineRect, cornerRadius: 2)
highlightColor.setFill()
path.fill()
context.restoreGState()
}
}
private func currentHighlightColor(range: NSRange) -> UIColor? {
guard let textStorage = textStorage else { return nil }
guard let highlightColor = textStorage.attributes(at: range.location, effectiveRange: nil)[.highlightColor] as? UIColor else { return nil }
return highlightColor
}
}
当用户单击它时,我设置范围的突出显示颜色并重置TextView。
attributedString.addAttributes([.highlightColor: theme.textUnderlineColor], range: range)