Swift NSTableView sample code

Swift – NSTableView Sample Code

  • Using Xcode 6.0 Create a new cocoa project and select the language as Swift
  • Modify the MainMenu.xib by
    • Adding a NSTableView from the library
    • Set the AppDelegate as the delegate and datasource for the table view
    • add two columns in the tableview and name them as FirstName and LastName
    • State the identifier of the two columns to FirstName and LastName respectively. We will be using an Array of Dictionaries with keys as FirstName and LastName
  • Modify the AppDelegate.swift class by adding the below code

Note: For the below code to work, the table view needs to be cell based (not view based). Scroll down for the updated example that includes a column containing checkboxes as well. That is the working code.

//
//  AppDelegate.swift
//  SwiftTableViewLoading
//
//  Created by Debasis Das on 6/2/14.
//  Copyright (c) 2014 KnowStack. All rights reserved.
//

import Cocoa
//In this sample code we are making the AppDelegate the datasource and delegate for our table
class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDataSource,NSTableViewDelegate {
                            
    @IBOutlet var window: NSWindow
    @IBOutlet var myTableView: NSTableView

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(aNotification: NSNotification?) {
        // Insert code here to tear down your application
    }

    func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
    {
        //let numberOfRows:Int = 20 
        let numberOfRows:Int = getDataArray().count
        return numberOfRows
    }
    
    func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject!
    {
//        var string:String = "row " + String(row) + ", Col" + String(tableColumn.identifier)
//        return string
        var newString = getDataArray().objectAtIndex(row).objectForKey(tableColumn.identifier)
        return newString;
    }

    func getDataArray () -> NSArray{
        var dataArray:NSDictionary[] = [["FirstName": "Debasis", "LastName": "Das"],
            ["FirstName": "Nishant", "LastName": "Singh"],
            ["FirstName": "John", "LastName": "Doe"],
            ["FirstName": "Jane", "LastName": "Doe"],
            ["FirstName": "Mary", "LastName": "Jane"]];
        println(dataArray);
        return dataArray;
    }
}

Output

Swift_NSTableView

 

Swift NSTableView – Editable NSCheckbox Cell

The following code base has an additional column for check box and edit / data state change implemented

SwiftTableViewCheckBox

Swift-TableView-Checkbox

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDataSource,NSTableViewDelegate {

@IBOutlet weak var window: NSWindow!
@IBOutlet weak var myTableView: NSTableView!

var dataArray:[NSMutableDictionary] = [[“firstName”: “Debasis”, “lastName”: “Das”, “fullTimeEmp”: 0],
  [“firstName”: “Nishant”, “lastName”: “Singh”, “fullTimeEmp”: 1],
  [“firstName”: “John”, “lastName”: “Doe”, “fullTimeEmp”: 1],
  [“firstName”: “Jane”, “lastName”: “Doe”, “fullTimeEmp”: 1],
    [“firstName”: “Mary”, “lastName”: “Jane”, “fullTimeEmp”: 0]];

  func applicationDidFinishLaunching(aNotification: NSNotification) 
  {
    // Insert code here to initialize your application
  }

  func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
  }

  func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
  {
    let numberOfRows:Int = dataArray.count
    return numberOfRows
  }

  func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject!
  {
    let object = dataArray[row] as NSMutableDictionary
    if ((tableColumn.identifier) == “fullTimeEmp”)
    {
      return object[tableColumn.identifier] as? Int!
    }
    else
    {
      return object[tableColumn.identifier] as? String!
    }
  }

  func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int)
  {
        dataArray[row].setObject(object!, forKey: (tableColumn?.identifier)!)
  }
}
Posted in Cocoa, Swift Tagged with: , , ,
21 comments on “Swift NSTableView sample code
  1. Iacopo says:

    This tutorial is great, thanks a lot!
    I edited the code to have a button that adds an entry to the existing array.
    The button works and if I println the array after pushing the button, the array has the new entry at the bottom, but I got stuck while trying to refresh the table view. What is the correct way to refresh the view any time the array is modified?
    Thanks again.

    • Iacopo says:

      I’ve actually managed to do that by using
      self.myTableView.reloadData()

    • XtN says:

      May I ask how did you do it so the button adds new entries to the array? I’m a newbie and can’t figure out how to deal with passing data to the array via button action. Thanks a lot!

  2. Matt says:

    Can you update the code to show how to add an entry to the table?

  3. Amir Masoud says:

    Thanks for the tutorial, but I was wondering how I should do the Key-value binding. I read that there are some problem. Is there any good article or sample code in this topic?

  4. Abdul says:

    Many thanks for the great code. Do you have a tip on how I can manage two tables within a view?

  5. Nicky says:

    Great tutorial, Thanks! Do you know a way to manually add a row or if the array of dicts is global and external call adds an additional element to the array to force the tableView to reload?
    Thanks!

    • Debasis Das says:

      Hi Nicky,

      The table view is UI and the array is the datasource. So once we have set the array as the datasource of the table view, one can simply add a row / object / Dictionary to the array and reload the table view. the new row will start reflecting.

      [self.myTableView reloadData]; if the myTableView is declared as a property or [_myTableView reloadData] should do the work]

  6. Steve Castaneda says:

    Any chance you could update this for Xcode 6.1? Can’t get it to work. http://stackoverflow.com/questions/25852994/nstextfield-keeps-repeating-title

    • Debasis Das says:

      sorry for delayed response

      Appears that you have figured out the solution and have updated the answer @ stackoverflow.

      The conflict would be resolved if the table view was made cell based.

  7. Jody Fluhr says:

    Your help is greatly appreciated, Debasis! Could you extend the example above to show a third column that includes a checkbox for each row? I am unable to control the state of the checkbox from my AppDelegate. I am using an Array Controller to display the contents of an array in AppDelegate in the NSTableView.

    Any and all help is greatly appreciated.

    • Debasis Das says:

      Hi Jody,
      Sorry for the delayed response.

      Have added the code for editing on table and changing state of a checkbox.
      You can download the code from the below location

      http://www.knowstack.com/wp-content/uploads/2014/06/SwiftTableViewCheckBox.zip

      import Cocoa

      @NSApplicationMain
      class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDataSource,NSTableViewDelegate {

      @IBOutlet weak var window: NSWindow!
      @IBOutlet weak var myTableView: NSTableView!

      var dataArray:[NSMutableDictionary] = [[“firstName”: “Debasis”, “lastName”: “Das”, “fullTimeEmp”: 0],
      [“firstName”: “Nishant”, “lastName”: “Singh”, “fullTimeEmp”: 1],
      [“firstName”: “John”, “lastName”: “Doe”, “fullTimeEmp”: 1],
      [“firstName”: “Jane”, “lastName”: “Doe”, “fullTimeEmp”: 1],
      [“firstName”: “Mary”, “lastName”: “Jane”, “fullTimeEmp”: 0]];

      func applicationDidFinishLaunching(aNotification: NSNotification) {
      // Insert code here to initialize your application
      }

      func applicationWillTerminate(aNotification: NSNotification) {
      // Insert code here to tear down your application
      }

      func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
      {
      let numberOfRows:Int = dataArray.count
      return numberOfRows
      }

      func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject!
      {
      let object = dataArray[row] as NSMutableDictionary
      if ((tableColumn.identifier) == “fullTimeEmp”)
      {
      return object[tableColumn.identifier] as? Int!
      }
      else
      {
      return object[tableColumn.identifier] as? String!
      }
      }

      func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int)
      {
      dataArray[row].setObject(object!, forKey: (tableColumn?.identifier)!)
      }
      }

  8. Martin K. says:

    Why does this line

    var newString:String = getDataArray().objectAtIndex(row).objectForKey(tableColumn.identifier)

    not work anymore with my Xcode 6.1.1?

    I’m getting ‘Cannot invoke ‘objectForKey’ with an argument of type ‘@lvalue String!’

    var id:String = tableColumn.identifier
    does work and ‘println(“ID: \(id))’ produces the expected “FirstName” and “Lastname” ;

    • Debasis Das says:

      Try this it should work
      let object = dataArray[row] as NSMutableDictionary
      if ((tableColumn.identifier) == “your identifier”)
      {
      return object[tableColumn.identifier] as? Int!
      }

    • Debasis Das says:

      Hi Martin,

      Try this approach, it should work
      You can download the working code from this location
      http://www.knowstack.com/wp-content/uploads/2014/06/SwiftTableViewCheckBox.zip

      import Cocoa

      @NSApplicationMain
      class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDataSource,NSTableViewDelegate {

      @IBOutlet weak var window: NSWindow!
      @IBOutlet weak var myTableView: NSTableView!

      var dataArray:[NSMutableDictionary] = [[“firstName”: “Debasis”, “lastName”: “Das”, “fullTimeEmp”: 0],
      [“firstName”: “Nishant”, “lastName”: “Singh”, “fullTimeEmp”: 1],
      [“firstName”: “John”, “lastName”: “Doe”, “fullTimeEmp”: 1],
      [“firstName”: “Jane”, “lastName”: “Doe”, “fullTimeEmp”: 1],
      [“firstName”: “Mary”, “lastName”: “Jane”, “fullTimeEmp”: 0]];

      func applicationDidFinishLaunching(aNotification: NSNotification) {
      // Insert code here to initialize your application
      }

      func applicationWillTerminate(aNotification: NSNotification) {
      // Insert code here to tear down your application
      }

      func numberOfRowsInTableView(aTableView: NSTableView!) -> Int
      {
      let numberOfRows:Int = dataArray.count
      return numberOfRows
      }

      func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject!
      {
      let object = dataArray[row] as NSMutableDictionary
      if ((tableColumn.identifier) == “fullTimeEmp”)
      {
      return object[tableColumn.identifier] as? Int!
      }
      else
      {
      return object[tableColumn.identifier] as? String!
      }
      }

      func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int)
      {
      dataArray[row].setObject(object!, forKey: (tableColumn?.identifier)!)
      }
      }

  9. Martin K. says:

    … and I had to switch the the content mode of my table view from ‘View Based’ to ‘Cell Based’ .

    All up and running now! :-)

  10. Craig says:

    That ‘View Based’ to ‘Cell Based’ check needs to be added as an instruction point, other than that, this is a PERFECT tutorial. Nicely done.

  11. Abdul says:

    Hi,
    the following code is not compatible with Swift3. Do you have a tip for me please?

    “var newString = getDataArray().objectAtIndex(row).objectForKey(tableColumn.identifier)
    return newString;”

    Many thanks.

1 Pings/Trackbacks for "Swift NSTableView sample code"
  1. […] Swift NSTableView sample code […]

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Recent Posts


Hit Counter provided by technology news