如何在AppKit的TextView中检测换行符?

时间:2019-07-07 18:25:52

标签: swift macos line-breaks appkit nstextview

一般思想:在NSScrollView(包含NSTextView)的文本段落中突出显示字符组。我从NSLayoutManager.boundingRect()获取所选字符的边界矩形,并用其坐标/大小代替字符来创建CAShapeLayer

问题在于,如果所讨论的字符范围跨越两行,则边界矩形将同时覆盖它们的高度和宽度,因此我需要在文本视图中为文本的每一行进行覆盖。

有问题的地方NSTextViewNSTextStorageNSTextContainer中的字符串属性返回没有换行符("\n")的字符串。我该怎么办

1)找到带换行符的文本视图的实际文本值吗?

2)使用其他技术遍历文本视图的行吗?

3)使用其他库来完成我的总体思路?

我的View Controller代码:


import Cocoa

class ViewController: NSViewController {


    @IBOutlet weak var textView: NSTextView!
    @IBOutlet weak var shapeView: NSView!


    override func viewDidLoad() {
        super.viewDidLoad()

        shapeView.wantsLayer = true

        textView.string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

    }


    @IBAction func checkButtonPressed(sender: NSButton) {

        let range = NSMakeRange(2, 5) //Creating a makeshift range for testing purposes
        let layoutManager = textView.layoutManager
        var textRect = NSRect()

        //Accessing bounding rectangle of the chosen characters
        textRect = (layoutManager?.boundingRect(forGlyphRange: range, in: textView.textContainer!))!

        //Creating a parent layer and assigning it as the main layer of the shape view
        let parentShapeLayer = CAShapeLayer()
        shapeView.layer = parentShapeLayer

        //Creating an actual rectangle - CAShapeLayer
        let shapeLayer = CAShapeLayer()
        parentShapeLayer.addSublayer(shapeLayer)
        parentShapeLayer.isGeometryFlipped = true
        shapeLayer.frame = textRect
        shapeLayer.backgroundColor = NSColor.yellow.cgColor

        if let string = textView.textStorage?.string {

            for var char in string {
                if (char == "\n") {
                    print(char) //Does not print anything
                }
            }
        }

    }


    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }


}

P.S。。我知道NSLayoutManager有方法drawBackground(),但无法找到所需的上下文,但这是一个不同的问题。

1 个答案:

答案 0 :(得分:0)

我已经找到了一种概念上的解决方法:我只为单个字符而不是字符组绘制矩形,因此避免了换行检测。并非最佳,但可以。