UITextView 绘制不可见/空白字符

Noo*_*ath 5 whitespace uitextview swift

如何绘制UITextView制表符、空格和换行符结尾的不可见字符?

我认为它必须在drawRect(CGRect) 方法中或由文本工具包中的布局管理器来处理。有什么简单和/或直观的解决方案吗?

我只需要知道如何获取CGRect每个空白字符以及哪种覆盖方法可以为每个空白字符无缝绘制图形?

预先感谢您的任何建议/帮助。
另外,我不介意你的答案是否是 Objective-C,尽管两种语言都是首选。

Noo*_*ath 3

我找到了比设置toshowsInvisibleCharacters的属性更好的解决方案,通过子类化 和重写 method ,它允许为每个空白字符自定义绘图,例如:NSLayoutManagertrueNSLayoutManagerdrawBackgroundForGlyphRange(NSRange, CGPoint)

class LayoutManager : NSLayoutManager {

    var text: String? { return textStorage?.string }

    var font: UIFont = UIFont.systemFontOfSize(UIFont.systemFontSize()) { 
        didSet { 
            guard let text = self.text else { return }
            let textRange = NSMakeRange(0, (text as NSString).length)                
            invalidateGlyphsForCharactersInRange(textRange, actualCharacterRange: nil)
            invalidateCharacterAttributesForCharactersInRange(textRange, actualCharacterRange: nil)
        }
    }

    override func drawBackgroundForGlyphRange(glyphsToShow: NSRange, atPoint origin: CGPoint) {

        super.drawBackgroundForGlyphRange(glyphsToShow, atPoint:origin)

        guard let text = self.text else { return }

        enumerateLineFragmentsForGlyphRange(glyphsToShow)
        { (rect: CGRect, usedRect: CGRect, textContainer: NSTextContainer, glyphRange: NSRange, stop: UnsafeMutablePointer<ObjCBool>) -> Void in

            let characterRange = self.characterRangeForGlyphRange(glyphRange, actualGlyphRange: nil)

            // Draw invisible tab space characters

            let line = (self.text as NSString).substringWithRange(characterRange)

            do {

                let expr = try NSRegularExpression(pattern: "\t", options: [])

                expr.enumerateMatchesInString(line, options: [.ReportProgress], range: line.range) 
                { (result: NSTextCheckingResult?, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) in

                    if let result = result {

                        let range = NSMakeRange(result.range.location + characterRange.location, result.range.length)
                        let characterRect = self.boundingRectForGlyphRange(range, inTextContainer: textContainer)

                        let symbol = "\u{21E5}"
                        let attrs = [NSFontAttributeName : Font]
                        let height = (symbol as NSString).sizeWithAttributes(attrs).height
                        symbol.drawInRect(CGRectOffset(characterRect, 1.0, height * 0.5, withAttributes: attrs)

                    }

                }

            } catch let error as NSError {
                print(error.localizedDescription)
            }

        }

    }

}
Run Code Online (Sandbox Code Playgroud)