Reputation: 135
I created a NSTableView in IB with 3 columns (first name, last name and email). I want to add a 4th one (age).
let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "age"))
column.title = "Age"
column.width = CGFloat(120)
column.minWidth = CGFloat(4)
self.tableView.addTableColumn(column)
The column is added but its content is empty.
I wonder if there is not an issue with the cell view but I don't know how to add it. Can somebody help?
Thank you.
The whole code is added below. Code in in Swift 4 Xcode 9
import Cocoa
class Person: NSObject {
var firstName : String
var lastName : String
var emailId : String
var age : Int
init(firstName: String, lastName: String, emailId: String, age: Int){
self.firstName = firstName
self.lastName = lastName
self.emailId = emailId
self.age = age
}
}
class ViewController: NSViewController {
@IBOutlet weak var tableView: NSTableView!
var tableViewData: [Person] = [Person(firstName: "John", lastName: "Apple", emailId: "[email protected]", age: 35),Person(firstName: "Phil", lastName: "Grant", emailId: "[email protected]", age: 50),Person(firstName: "lou", lastName: "groth", emailId: "[email protected]", age: 14)]
override func viewDidLoad() {
super.viewDidLoad()
let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "age"))
column.title = "Age"
column.width = CGFloat(120)
column.minWidth = CGFloat(4)
self.tableView.addTableColumn(column)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.reloadData()
}
}
extension ViewController:NSTableViewDataSource, NSTableViewDelegate{
func numberOfRows(in tableView: NSTableView) -> Int {
return tableViewData.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?{
guard let vw = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTableCellView else { return nil }
switch tableColumn?.identifier.rawValue {
case "firstName"?:
vw.textField?.stringValue = tableViewData[row].firstName
case "lastName"?:
vw.textField?.stringValue = tableViewData[row].lastName
case "emailId"?:
vw.textField?.stringValue = tableViewData[row].emailId
case "age"?:
vw.textField?.integerValue = tableViewData[row].age
default:
return nil
}
return vw
}
}
Upvotes: 3
Views: 2114
Reputation: 136
I know this is old, but someone might find this helpful. Docs for makeView says:
If a view with the specified identifier can’t be instantiated from the nib file or found in the reuse queue, this method returns nil.
If you add a column programmatically it won't be in the nib, so makeView will return nil and your column will be empty. To make it show, you could use NSTextField instead of NSTableCellView like this:
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?
{
var vw = tableView.makeView(withIdentifier: tableColumn!.identifier, owner: self) as? NSTextField
if vw == nil
{
vw = NSTextField(labelWithString: "")
vw?.identifier = tableColumn!.identifier // allows this new cell to be reused
}
switch tableColumn?.identifier.rawValue {
case "firstName":
vw?.stringValue = tableViewData[row].firstName
case "lastName":
vw?.stringValue = tableViewData[row].lastName
case "emailId":
vw?.stringValue = tableViewData[row].emailId
case "age":
vw?.stringValue = String(tableViewData[row].age)
default:
return nil
}
return vw
}
Upvotes: 1
Reputation: 6707
Use the identifier property.
let tableColumn = NSTableColumn()
tableColumn.headerCell.title = "Age"
tableColumn.headerCell.alignment = .center
tableColumn.identifier = "age"
self.tableView.addTableColumn(tableColumn)
Upvotes: 2