如何使NSTextView的高度始终高于实际20px的高度?

时间:2018-08-05 14:26:46

标签: swift macos cocoa nstextview

我正在使用NSTextView作为文本编辑器,我想使其比用户输入文本后重新计算的高度高20 PX。

也就是说,当NSTextView在NSScrollView的末尾滚动时,将出现一个空白区域,使用户不必输入回车符即可生成空白行。这样,尾巴的文本将始终位于上方,以方便用户的视觉体验。

您如何做到的?

How to resize NSTextView according to its content?

我在此问题中发现了一些提示,但连接时间过长后无效。

1 个答案:

答案 0 :(得分:0)

由于您的NSTextView通常嵌套在NSScrolView内,因此您可以使用滚动视图的边距进行游戏。

下面的解决方案是针对基于情节提要的应用程序,它对OS X 10.10(Yosemite)的最低要求为:

class ViewController: NSViewController {
    @IBOutlet weak var scrollView: NSScrollView!
    @IBOutlet weak var textView: NSTextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        textView.layoutManager?.delegate = self
        scrollView.automaticallyAdjustsContentInsets = false
    }
}

extension ViewController: NSLayoutManagerDelegate {
    func layoutManager(_ layoutManager: NSLayoutManager, didCompleteLayoutFor textContainer: NSTextContainer?, atEnd layoutFinishedFlag: Bool) {
        guard let textContainer = textContainer else { return }

        let textRect = layoutManager.usedRect(for: textContainer)
        let bottomSpace: CGFloat = 20.0
        let bottomInset: CGFloat = (textRect.height + bottomSpace) > scrollView.bounds.height ? bottomSpace : 0

        scrollView.contentInsets.bottom = bottomInset
        scrollView.scrollerInsets.bottom = -bottomInset
    }
}

编辑: 如果单击底部空格,如何滚动文本视图?

您可以使用NSParagraphStyle来在最后一段之后添加一些内容。或者,您可以使用Responder Chain并使视图控制器将光标位置更改为文本视图的末尾:

class ViewController: NSViewController {
    // ...

    override func mouseUp(with event: NSEvent) {
        let bottomSpace = scrollView.contentInsets.bottom
        let clickLocation = self.view.convert(event.locationInWindow, to: textView)
        let bottomRect = CGRect(x: 0, y: textView.bounds.height, width: textView.bounds.width, height: bottomSpace)

        if bottomRect.contains(clickLocation) {
            textView.moveToEndOfDocument(self)
        }
    }
}

如果您希望具有相同行为的多个文本视图,请花时间设计自己的课程。