默认布局管理器填充没有文本(最后一行除外)的背景颜色(通过 NSAttributedString .backgroundColor 属性指定)。
我已经通过子类化 NSLayoutManager 并覆盖 func drawBackground(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) 来实现我想要的效果,如下所示:
但是,这不能处理属性字符串中由范围指定的多种颜色的可能性。我怎样才能做到这一点?我看过 fillBackgroundRectArray 却收效甚微。
Best Answer-推荐答案 strong>
How might I achieve this?
这是我如何达到您的目标,在著名的 Lorem ipsum... 中以不同颜色突出显示 “sit” 术语,该术语足以在多个测试中进行测试行。
支持以下代码的所有基础(Swift 5.1,iOS 13)在 this answer 中提供为清楚起见,不会在此处复制⟹它们导致了结果1。
在您的情况下,您想突出显示字符串的某些特定部分,这意味着这些元素由于其内容而应具有专用的关键属性⟹在我看来,这取决于 textStorage 来处理用它。
MyTextStorage.swift
// Sent when a modification appears via the 'replaceCharacters' method.
override func processEditing() {
var regEx: NSRegularExpression
do {
regEx = try NSRegularExpression.init(pattern: " sit ", options: .caseInsensitive)
let stringLength = backingStorage.string.distance(from: backingStorage.string.startIndex,
to: backingStorage.string.endIndex)
regEx.enumerateMatches(in: backingStorage.string,
options: .reportCompletion,
range: NSRange(location: 1, length: stringLength-1)) { (result, flags, stop) in
guard let result = result else { return }
self.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.black, //To be seen above every colors.
NSAttributedString.Key.backgroundColor : UIColor.random()],
range: result.range)
}
} catch let error as NSError {
print(error.description)
}
super.processEditing()
}
}
//A random color is provided for each " sit " element to highlight the possible different colors in a string.
extension UIColor {
static func random () -> UIColor {
return UIColor(red: CGFloat.random(in: 0...1),
green: CGFloat.random(in: 0...1),
blue: CGFloat.random(in: 0...1),
alpha: 1.0)
}
}
如果你从这里构建并运行,你会得到结果 2 显示文本中 "sit" 的每个彩色背景都有问题 ⟹ 有一个偏移量lineFragment 和彩色背景矩形之间。 |