如何根据内容自动调整 NSTextView 的大小?
How to resize a NSTextView automatically as per its content?
我正在制作一个应用程序,用户可以在其中单击 window 上的任意位置,并在鼠标位置以编程方式添加 NSTextView
。我已经让它与下面的代码一起工作,但我希望这个 NSTextView
水平扩展直到到达屏幕边缘,然后垂直增长。它目前具有固定宽度,当我添加更多字符时,文本视图会垂直增长(如预期的那样),但我也希望它水平增长。我怎样才能做到这一点?
我已经尝试将 isHorizontallyResizable
和 isVerticallyResizable
设置为 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
中,而 NSView
是 NSViewController
的一部分,然后您在谈论屏幕宽度。这是您的 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)
}
}
我正在制作一个应用程序,用户可以在其中单击 window 上的任意位置,并在鼠标位置以编程方式添加 NSTextView
。我已经让它与下面的代码一起工作,但我希望这个 NSTextView
水平扩展直到到达屏幕边缘,然后垂直增长。它目前具有固定宽度,当我添加更多字符时,文本视图会垂直增长(如预期的那样),但我也希望它水平增长。我怎样才能做到这一点?
我已经尝试将 isHorizontallyResizable
和 isVerticallyResizable
设置为 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
中,而 NSView
是 NSViewController
的一部分,然后您在谈论屏幕宽度。这是您的 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)
}
}