我正在尝试使用NSAttributedString原生地渲染一个“高光”,我注意到它在iOS 10上非常漂亮,在iOS 11上非常无聊。我可以说iOS 10的渲染是正确的。
iOS 10:

iOS 11显然是错误的,但我猜他们出于性能原因决定牺牲一些绘图计算。
iOS 11:

我尝试了各种设置,但似乎不可能“轻松”实现在iOS 11上渲染iOS 10,这意味着不编写任何自定义字符串绘制代码。
发布于 2019-05-13 21:04:40
所以,我最终找到了一个可靠的解决方案,实际上很简单。您需要有一个LayoutManager,所以最好使用UITextView或您自己的自定义文本抽屉。下面是我的自定义UITextView子类:
class QuoteTextView: UITextView, NSLayoutManagerDelegate {
var highlightColor = UIColor.gl_defaultHighlight
override var text: String! {
didSet {
setNeedsDisplay()
}
}
override func awakeFromNib() {
super.awakeFromNib()
let padding = textContainer.lineFragmentPadding
textContainerInset = UIEdgeInsets(top: 0, left: -padding, bottom: 0, right: -padding)
layoutManager.delegate = self
}
override func draw(_ rect: CGRect) {
super.draw(rect)
layoutManager.enumerateLineFragments(forGlyphRange: NSMakeRange(0, text.utf16.count)) { (rect1, lineRect, container, range, _) in
let path = UIBezierPath(rect: CGRect(x: lineRect.origin.x,
y: lineRect.origin.y - 2,
width: lineRect.size.width,
height: lineRect.size.height - 4))
self.highlightColor.setFill()
path.fill()
}
}
func layoutManager(_ layoutManager: NSLayoutManager,
lineSpacingAfterGlyphAt glyphIndex: Int,
withProposedLineFragmentRect rect: CGRect) -> CGFloat {
return 5
}
func layoutManager(_ layoutManager: NSLayoutManager,
shouldUse action: NSLayoutManager.ControlCharacterAction,
forControlCharacterAt charIndex: Int) -> NSLayoutManager.ControlCharacterAction {
return .lineBreak
}
}https://stackoverflow.com/questions/50912854
复制相似问题