如何根据内容自动调整 NSTextView 的大小?

How to resize a NSTextView automatically as per its content?

我正在制作一个应用程序,用户可以在其中单击 window 上的任意位置,并在鼠标位置以编程方式添加 NSTextView。我已经让它与下面的代码一起工作,但我希望这个 NSTextView 水平扩展直到到达屏幕边缘,然后垂直增长。它目前具有固定宽度,当我添加更多字符时,文本视图会垂直增长(如预期的那样),但我也希望它水平增长。我怎样才能做到这一点?

我已经尝试将 isHorizontallyResizableisVerticallyResizable 设置为 true 但这不起作用。研究了一段时间后,我遇到了这个 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextStorageLayer/Tasks/TrackingSize.html 但这对我也不起作用。

ViewController 中的代码,用于将 NSTextView 添加到其视图中:

private func addText(at point: NSPoint) {     
    let textView = MyTextView(frame: NSRect(origin: point, size: CGSize(width: 150.0, height: 40.0)))
    view.addSubview(textView)       
}

而且,MyTextView class 如下所示:

class MyTextView: NSTextView {

    override func viewWillDraw() {
        
        isHorizontallyResizable = true
        isVerticallyResizable = true
        
        isRichText = false
    }
}

我也看到了这个答案,但我不太确定如何实现它。我在 MyTextView 中添加了这个代码片段并像这样使用它:

override func didChangeText() {
    frame.size = contentSize
}

但是,我认为我使用不正确。因此,我们将不胜感激。

我终于让它工作了(除了一件小事)。 Apple 的 link 是这里的关键,但不幸的是,他们没有完整地描述代码。

下面的代码对我有用:

class MyTextView: NSTextView {
    override func viewWillDraw() {
        // for making the text view expand horizontally
        textContainer?.heightTracksTextView = false
        textContainer?.widthTracksTextView = false
        textContainer?.size.width = 10000.0
        maxSize = NSSize(width: 10000.0, height: 10000.0)
        isHorizontallyResizable = true
        isVerticallyResizable = true

        isRichText = false
    }
}

我还没有弄清楚的一件小事是限制水平扩展直到到达屏幕边缘。现在它继续扩展甚至超出屏幕宽度,反过来,文本隐藏在屏幕宽度之后。

我想如果我能以某种方式获得 screen window 宽度,那么我可以将 10000.0 替换为屏幕宽度(减去文本视图的距离)从左边缘),我可以限制水平扩展直到屏幕边缘。话虽如此,保留它 10000.0 不会影响 Apple 文档中所述的性能。

我有点疑惑,因为您要将 NSTextView 添加到 NSView 中,而 NSViewNSViewController 的一部分,然后您在谈论屏幕宽度。这是您的 Presentify - Screen Annotation 应用程序的一部分吗?如果是,则您有一个全屏覆盖 window 并且您可以从中获取尺寸(或从视图控制器的视图)。

view.bounds.size                // view controller's view size
view.window?.frame.size         // window size

如果不是并且您确实需要知道屏幕尺寸,请检查 NSWindow & NSScreen

view.window?.screen?.frame.size // screen size

不断增长的 NSTextView

没有指定任何 window/view 控制器的视图大小调整行为。

import Cocoa

class BorderedTextView: NSTextView {
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        
        let path = NSBezierPath(rect: bounds)
        NSColor.red.setStroke()
        path.stroke()
    }
}

class ViewController: NSViewController {
    override func mouseUp(with event: NSEvent) {
        // Convert point to the view coordinates
        let point = view.convert(event.locationInWindow, from: nil)
        
        // Initial size
        let size = CGSize(width: 100, height: 25)
        
        // Maximum text view width
        let maxWidth = view.bounds.size.width - point.x             // <----
                
        let textView = BorderedTextView(frame: NSRect(origin: point, size: size))
        textView.insertionPointColor = .orange
        textView.drawsBackground = false
        textView.textColor = .white
        textView.isRichText = false
        textView.allowsUndo = false
        textView.font = NSFont.systemFont(ofSize: 20.0)
        textView.isVerticallyResizable = true
        textView.isHorizontallyResizable = true
                
        textView.textContainer?.widthTracksTextView = false
        textView.textContainer?.heightTracksTextView = false
        textView.textContainer?.size.width = maxWidth               // <----
        textView.maxSize = NSSize(width: maxWidth, height: 10000)   // <----
        
        view.addSubview(textView)
        
        view.window?.makeFirstResponder(textView)
    }
}