macOS NSTableView Tutorial

Table views are one of the most important macOS UI controls. Get up to speed with how to use them with this macOS NSTableView tutorial. By Warren Burton.

Leave a rating/review
Save for later
Share

Update note: This macOS NSTableView tutorial has been updated to Xcode 8 and Swift 3 by Warren Burton. The original tutorial was written by Ernesto García.

Update note: This macOS NSTableView tutorial has been updated to Xcode 8 and Swift 3 by Warren Burton. The original tutorial was written by Ernesto García.

Table views are one of the most ubiquitous controls in macOS applications, with familiar examples being Mail’s message list and Spotlight’s search results. They allow your Mac to represent tabular data in an attractive way.

NSTableView arranges data in rows and columns. Each row represents a single model object within a given data collection, and each column displays a specific attribute of a model object.

In this macOS NSTableView tutorial, you’ll use a table view to create a functional file viewer that will bear a striking resemblance to Finder. As you work through it, you’ll learn a lot about table views, such as:

  • How to populate a table view.
  • How to change its visual style.
  • How to react to user interaction, like a selection or double-click.

Ready to create your first table view? Read on!

Getting Started

Download the starter project and open it in Xcode.

Build and run to see what you’re starting with:

window at start of tutorial

You have a blank canvas from which you’ll create a cool file viewer. The starter app already has some of the functionality you’ll need to work through this tutorial.

With the application open, choose File > Open… (or use the Command+O keyboard shortcut).

open a folder

From the new window that pops up, choose any folder you want and click the Open button. You’ll see something like this in Xcode’s console:

Represented object: file:///Users/tutorials/FileViewer/FileViewer/ 

This message shows the selected folder’s path, and the code in the starter project passes that URL to the view controller.

If you’re curious and want to learn more about how things are implemented, here’s where you should look:

  • Directory.swift: Contains the implementation of the Directory struct that reads the content of a directory.
  • WindowController.swift: Contains the code that presents you with the folder selection panel and passes the selected directory to the ViewController.
  • ViewController.swift: Contains the implementation of the ViewController class and is where you’ll spend some time today. It’s where you’ll create the table view and show the file list.

Creating the Table View

Open Main.storyboard in the Project Navigator. Select the View Controller Scene and drop a table view from the Object Library into the view. There’s a container in the view hierachy named Table Container all ready for you.

add a table in interface builder

Next, you need to add some constraints. Click the Pin button in the Auto Layout toolbar. In the popup that appears, set the all the edge constraints as follows:

  • Top, Bottom, Leading and Trailing: 0.

constrain the table to its container

Be sure to set Update Frames to Items of New Constraints, then click Add 4 Constraints.

Take a moment to have a look at the structure of a newly created table view. As you probably gathered from its name, it follows typical table structuring:

  • It’s made up of rows and columns.
  • Each row represents a single item within the data model collection.
  • Each column displays specific attributes of the model.
  • Each column can also have a header row.
  • Header rows describe the data within a column.

table view inner structure

If you’re familiar with UITableView on iOS, you’re treading familiar waters, but they’re much deeper here in macOS. In fact, you might be surprised by the number of individual UI objects in the object hierarchy that make up an NSTableView.

NSTableView is an older and more complex control than a UITableView, and it serves a different user interface paradigm, specifically, where the user has a mouse or trackpad.

The main difference with UITableView is that you have the possibility of multiple columns and a header that can be used to interact with the table view, for example, ordering and selecting.

Together, NSScrollView and NSClipView, respectively scroll and clip the contents of the NSTableView.

There are two NSScroller objects — one each for vertical and horizontal scrolling across the table.

There are also a number of column objects. An NSTableView has columns, and these columns have headers with titles. It’s important to note that users can resize and reorder columns, though you have the power to remove this ability by setting its default to disabled.

Anatomy of NSTableView

In Interface Builder, you’ve seen the complexity of the view hierarchy of the table view. Multiple classes cooperate to build the table structure, which usually ends up looking like this:

components of a table view

These are the key parts of an NSTableView:

  • Header View: The header view is an instance of NSTableHeaderView. It’s responsible for drawing the headers at top of the table. If you need to display a custom header, you can use your own header subclasses.
  • Row View: The row view displays the visual attributes associated with every row in the table view, like a selection highlight. Each row displayed in the table has its own instance of the row view. An important distinction to make is that rows do not represent your data; that the cell’s responsibility. It only handles visual attributes like selection color or separators. You can create new row subclasses to style your table view differently.
  • Cell Views: The cell is arguably the most important object in a table view. At the intersection of a row and column, you find a cell. Each one is an NSView or NSTableCellView subclass, and its responsibility is to display the actual data. And guess what? You can create custom cell view classes to display the content however you’d like.
  • Column: The columns are represented by the NSTableViewColumn class, which is responsible for managing width and behavior of the column, such as resizing and repositioning. This class is not a view, but a controller class. You use it to specify how columns should behave, but you don’t control the visual styles of the columns with it because the header, row and cell views have got things covered.

Note: There are two modes of NSTableView. The first is a cell-based table view called an NSCell. It’s like an NSView, but older and lighter. It comes from earlier days of computing when the desktop needed optimizations in order to draw controls with minimal overhead.

Apple recommends using view-based table views, but you’ll see NSCell in many of the controls in AppKit, so it’s worth knowing what it is and where it comes from. You can read more about NSCell in Apple’s Control and Cell Programming Topics

Note: There are two modes of NSTableView. The first is a cell-based table view called an NSCell. It’s like an NSView, but older and lighter. It comes from earlier days of computing when the desktop needed optimizations in order to draw controls with minimal overhead.

Apple recommends using view-based table views, but you’ll see NSCell in many of the controls in AppKit, so it’s worth knowing what it is and where it comes from. You can read more about NSCell in Apple’s Control and Cell Programming Topics

Well, now that was a nice little jog into the basic theory behind table view structure. Now that you’ve had all that, it’s time to go back to Xcode and get to work on your very own table view.