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
}

Get the Swift Dev Journal Newsletter

Subscribe and get exclusive articles, a free guide on moving from tutorials to making your first app, notices of sales on books, and anything I decide to add in the future.

    We won't send you spam. Unsubscribe at any time.