This tutorial is very similar to the previous one, the only difference that now, we will use a Person model, that will make you life easier.
So, the final will be the same:
Step 1. Create a Cocoa Application project.
Step 2. Add NSTableView to the Main Storyboard and customize a little bit
Increase the number of columns from 2 to 3.
Click on the header and name the columns
We need to add identifier to the columns and cells. You should repeat this to the Last name(lastName) and Mobile number(mobileNumber) columns and cells as well.
Create an IBOutlet and connect it to your tableview but don’t forget the dataSource and delegate either.
@IBOutlet var tableView: NSTableView!
So, instead of creating an Array with Dictionary, we add a new file.
import Cocoa
struct Person {
let firstName: String
let lastName: String
let mobileNumber: String
}
We have the Person model, we need to add some values to it, but first create an array.
@IBOutlet var tableView: NSTableView!
var people: [Person] = []
override func viewDidLoad() {
super.viewDidLoad()
let person1 = Person.init(firstName: "Ragnar", lastName: "Lothbrok", mobileNumber: "555-1234")
let person2 = Person.init(firstName: "Bjorn", lastName: "Lothbrok", mobileNumber: "555-3412")
let person3 = Person.init(firstName: "Harald", lastName: "Finehair", mobileNumber: "555-4512")
people.append(person1)
people.append(person2)
people.append(person3)
}
We need to implement the following two methods:
- How many rows will we need?
- and what will be the values of the cells
It is considered to be a good practice to separate delegates from the main code as extension, so the following won’t be added directly to the ViewController
.
func numberOfRows(in tableView: NSTableView) -> Int {
return (people.count)
}
We would like to match the NSDictionary key to the column identifier and give the NSDictionary value to the cell.
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let person = people[row]
guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil }
if (tableColumn?.identifier)!.rawValue == "firstName" {
cell.textField?.stringValue = person.firstName
} else if (tableColumn?.identifier)!.rawValue == "lastName" {
cell.textField?.stringValue = person.lastName
} else {
cell.textField?.stringValue = person.mobileNumber
}
return cell
}
It is very important that your NSDictionary keys must match with the identifiers of your columns otherwise it won’t work.
I copy the full code here below.
mport Cocoa
class ViewController: NSViewController {
@IBOutlet var tableView: NSTableView!
var people: [Person] = []
override func viewDidLoad() {
super.viewDidLoad()
let person1 = Person.init(firstName: "Ragnar", lastName: "Lothbrok", mobileNumber: "555-1234")
let person2 = Person.init(firstName: "Bjorn", lastName: "Lothbrok", mobileNumber: "555-3412")
let person3 = Person.init(firstName: "Harald", lastName: "Finehair", mobileNumber: "555-4512")
people.append(person1)
people.append(person2)
people.append(person3)
}
}
extension ViewController: NSTableViewDataSource, NSTableViewDelegate {
func numberOfRows(in tableView: NSTableView) -> Int {
return (people.count)
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let person = people[row]
guard let cell = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil }
if (tableColumn?.identifier)!.rawValue == "firstName" {
cell.textField?.stringValue = person.firstName
} else if (tableColumn?.identifier)!.rawValue == "lastName" {
cell.textField?.stringValue = person.lastName
} else {
cell.textField?.stringValue = person.mobileNumber
}
return cell
}
}
Source code: Github