NSLayoutManager boundingRectForGlyphRange由某些点closures

我想在UITextView中“突出显示”特定的单词,而不是用纯色(可能通过NSAttributedString ),而是使用渐变,也许还有一些奇特的效果。

因此,我决定有必要手动创build一个视图,并使用给定文本的边界矩形覆盖(或底层)。

令我惊讶的是,这竟然是相当简单的。 例子是在UIViewController里面, txtView是一个UITextView作为IBOutlet连接:

 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // Converting to NSString as I need a NSRange for glphyRangeForCharacterRange // (a normal String in Swift returns a Range) let charRange = (txtView.text as NSString).rangeOfString("dolor sit er elit") assert(charRange.location != NSNotFound, "Character Range could not be found.") let glyphRange = txtView.layoutManager.glyphRangeForCharacterRange(charRange, actualCharacterRange: nil) let glyphContainer = txtView.layoutManager.textContainerForGlyphAtIndex(glyphRange.location, effectiveRange: nil) let glyphRect = txtView.layoutManager.boundingRectForGlyphRange(glyphRange, inTextContainer: glyphContainer!) let highlightView = UIView(frame: glyphRect) highlightView.alpha = 0.3 highlightView.backgroundColor = UIColor.redColor() txtView.addSubview(highlightView) } 

不幸的是,这导致了覆盖视图(在下面的屏幕截图中是红色的),被closures了几个点。

模拟器屏幕截图显示红色的矩形被关闭了几个点

它似乎总是相同的数额。 这意味着我可能硬编码,但这从来不是一个好主意。 使用各种设备在模拟器上进行testing,并在具有iOS 8.1.3的iPhone 6上进行testing。

我也尝试过其他变体(通过创build我自己的NSTextContainer等) ,如何得到一个子string的CGRect的问题的启发和“boundingRectForGlyphRange并不总是适用于所有string”

任何想法(除了诉诸CoreText )?

尝试通过textview的textContainerInset调整glyph rect:

 var glyphRect = txtView.layoutManager.boundingRectForGlyphRange(glyphRange, inTextContainer: glyphContainer!) glyphRect.origin.y += txtView.textContainerInset.top 

这应该够了吧!