Using a Scrollable Text View in a Mac SwiftUI App
In the article Using Text Views in a SwiftUI App I showed how to use a UIKit text view in a SwiftUI app. But if you use the code from that article in a Mac app, you’ll run into a problem. The text view won’t scroll when you reach the bottom of the text view. In this article you’ll learn how to make the text view scroll in a Mac app.
Much of the code for this article comes from the CodeEditor Swift package, which is a text editor for SwiftUI with syntax highlighting.
Create a Scroll View
The reason the text view won’t scroll is that Mac text views aren’t wrapped in scroll views like iOS text views are. When you create the text view, you have to create both a text view and a scroll view. Set the scroll view’s document view to the text view. Give the scroll view a vertical scroller. Return the scroll view.
func makeNSView(context: Context) -> NSScrollView {
let textView = NSTextView()
textView.autoresizingMask = [.width, .height]
textView.isEditable = true
textView.delegate = context.coordinator
textView.allowsUndo = true
let scrollView = NSScrollView()
scrollView.hasVerticalScroller = true
scrollView.documentView = textView
return scrollView
}
Setting the autoresizing mask ensures the text view resizes properly when the window resizes.
Updating the View
When writing the updateNSView
function, supply the scroll view as the argument. Use the documentView
property of the scroll view to access the text view and update its contents.
func updateNSView(_ scrollView: NSScrollView, context: Context) {
guard let textView = scrollView.documentView
as? NSTextView else {
assertionFailure("unexpected text view")
return
}
if textView.delegate !== context.coordinator {
textView.delegate = context.coordinator
}
// model is your data model whose text you are
// showing and editing in the text view.
textView.string = model.text
}