How to make scrollable NSTextView in AppKit

Issue #330

When adding NSTextView in xib, we see it is embedded under NSClipView. But if we try to use NSClipView to replicate what’s in the xib, it does not scroll.

To make it work, we can follow Putting an NSTextView Object in an NSScrollView and How to make scrollable vertical NSStackView to make our ScrollableInput

For easy Auto Layout, we use Anchors for UIScrollView.

Things worth mentioned for vertical scrolling

1
2
3
textContainer.heightTracksTextView = false
textView.autoresizingMask = [.width]
textView.isVerticallyResizable = true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class ScrollableInput: NSView {
let scrollView = NSScrollView()
let textView = NSTextView()

override init(frame frameRect: NSRect) {
super.init(frame: frameRect)

let rect = CGRect(
x: 0, y: 0,
width: 0, height: CGFloat.greatestFiniteMagnitude
)

let layoutManager = NSLayoutManager()

let textContainer = NSTextContainer(size: rect.size)
layoutManager.addTextContainer(textContainer)
textView = NSTextView(frame: rect, textContainer: textContainer)
textView.maxSize = NSSize(width: 0, height: CGFloat.greatestFiniteMagnitude)

textContainer.heightTracksTextView = false
textContainer.widthTracksTextView = true

textView.isRichText = false
textView.importsGraphics = false
textView.isEditable = true
textView.isSelectable = true
textView.font = R.font.text
textView.textColor = R.color.text
textView.isVerticallyResizable = true
textView.isHorizontallyResizable = false

addSubview(scrollView)
scrollView.hasVerticalScroller = true
scrollView.drawsBackground = false
scrollView.drawsBackground = false
textView.drawsBackground = false

activate(
scrollView.anchor.edges
)

scrollView.documentView = textView
textView.autoresizingMask = [.width]
}

required init?(coder decoder: NSCoder) {
fatalError()
}
}

From macOS 10.14, we can use NSTextView.scrollableTextView()

Updated at 2020-12-31 05:43:41

Comments