简体   繁体   English

NSLayoutManager boundingRectForGlyphRange由某些点关闭

[英]NSLayoutManager boundingRectForGlyphRange off by some Points

I want to "highlight" specific words in UITextView, not with a solid color (which would be possible via NSAttributedString ), but rather with a gradient and maybe some other fancy effects. 我想“突出”UITextView中的特定单词,而不是纯色(可以通过NSAttributedString ),而是使用渐变和其他一些奇特的效果。

Hence, I decided it would be necessary to manually create a view and overlay (or underlay) it using the bounding rectangles of the given text. 因此,我决定有必要使用给定文本的边界矩形手动创建视图并覆盖(或底层)它。

To my surprise this turned out to be pretty straightforward. 令我惊讶的是,事实证明这非常简单。 Example is inside a UIViewController, txtView being a UITextView connected as IBOutlet : 示例在UIViewController中, txtView是作为IBOutlet连接的UITextView

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)
}

Sadly, this leads to the overlain view (in red in the below screenshot), being off by a few points. 可悲的是,这导致了覆盖的视图(在下面的屏幕截图中为红色),被几个点关闭。

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

It always seems to be off by the same amount. 它似乎总是相同数量。 Which would mean I could probably hardcode, but that has never been a good idea. 这意味着我可能会硬编码,但这从来都不是一个好主意。 Tested this in Simulator with various devices and on an iPhone 6 with iOS 8.1.3. 在Simulator中使用各种设备和带有iOS 8.1.3的iPhone 6进行了测试。

I also tried other variations (by creating my own NSTextContainer etc.) as inspired by the question on how to get a CGRect for a substring and "boundingRectForGlyphRange does not always work for all strings" 我还尝试了其他变体(通过创建我自己的NSTextContainer等),受到关于如何获得子串的CGRect的问题的启发,并且“boundingRectForGlyphRange并不总是适用于所有字符串”

Any ideas (besides resorting to CoreText )? 任何想法(除了诉诸CoreText )?

Try adjusting the glyph rect by the textview's textContainerInset: 尝试通过textview的textContainerInset调整字形rect:

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

glyphRect.origin.y += txtView.textContainerInset.top

That should do the trick! 这应该够了吧!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM