NSLayoutManager boundingRectForGlyphRange由某些点关闭

Lui*_*ell 6 objective-c core-text ios textkit swift

我想在UITextView中"突出显示"特定的单词,而不是使用纯色(这可能是通过NSAttributedString),而是使用渐变和其他一些奇特的效果.

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

令我惊讶的是,事实证明这非常简单.实施例是一个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)
}
Run Code Online (Sandbox Code Playgroud)

可悲的是,这导致了覆盖的视图(在下面的屏幕截图中为红色),被几个点关闭.

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

它似乎总是相同数量.这意味着我可能会硬编码,但这从来都不是一个好主意.在Simulator中使用各种设备和带有iOS 8.1.3的iPhone 6进行了测试.

我还尝试了其他变体(通过创建我自己的NSTextContainer等),受到关于如何获得子串的CGRect的问题的启发,并且"boundingRectForGlyphRange并不总是适用于所有字符串"

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

Geo*_*een 8

尝试通过textview的textContainerInset调整字形rect:

var glyphRect = txtView.layoutManager.boundingRectForGlyphRange(glyphRange,
        inTextContainer: glyphContainer!)

glyphRect.origin.y += txtView.textContainerInset.top
Run Code Online (Sandbox Code Playgroud)

这应该够了吧!