Returns NSView but constructed as NSTextField ... How does this translate into Swift ? ...
- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row {
// Get an existing cell with the MyView identifier if it exists
NSTextField *result = [tableView makeViewWithIdentifier:@"MyView" owner:self];
// There is no existing cell to reuse so create a new one
if (result == nil) {
// Create the new NSTextField with a frame of the {0,0} with the width of the table.
// Note that the height of the frame is not really relevant, because the row height will modify the height.
result = [[NSTextField alloc] initWithFrame:...];
// The identifier of the NSTextField instance is set to MyView.
// This allows the cell to be reused.
result.identifier = @"MyView";
}
// result is now guaranteed to be valid, either as a reused cell
// or as a new cell, so set the stringValue of the cell to the
// nameArray value at row
result.stringValue = [self.nameArray objectAtIndex:row];
// Return the result
return result;
}
OK, this has gone completely in the wrong direction. Let's go back to your original issue. Well, issues, plural.
The first thing: If you look at this documentation page:
https://developer.apple.com/documentation/appkit/nstableview/1535482-makeviewwithidentifier
you'll see that the method gets a "new or existing" cell. There is absolutely no need to create your own cell manually if "makeViewWithIdentifier" fails. The older documentation that you linked to is essentially wrong on this point.
Instead, if "makeViewWithIdentifier" returns nil, your code should assert, because this is a programmer error — you haven't configured something correctly in IB.
The second thing is that the table cell is almost always a subclass of NSTableCellView. NSTextField is not. When you create a table view in IB, it preconfigures the column to contain a NSTableCellView with a NSTextField as a subview, connected to the parent NSTableCellView's "textField" outlet. You need to return a NSTableCellView, not a NSTextField.
The third thing is that there are typically two identifiers involved: One is the table column identifier, which tells your code which column's cell is wanted in the "viewForTableColumn:" method. The other is the table cell identifier, which your code uses to tell "makeViewWithIdentifier" which cell you want. By default, a table view is created in IB with these two identifiers automatically locked together. You would normally write something like this:
let cell = tableView.makeView(withIdentifier: tableColumn.identifier, owner: self) as! NSTableCellView
cell.textField.stringValue = …
This isn't quite right, because "tableColumn" is optional, because this method is also called to get custom row views, and in that case "tableColumn" is nil. Your actual code, therefore, will look more like this:
guard let identifer = tableColumn?.identifier else { return nil }
let cell = tableView.makeView(withIdentifier: identifer, owner: self) as! NSTableCellView
cell.textField.stringValue = …
If you find this crashing because of the "as! NSTableCellView", that probably indicates that your table cell identifier doesn't match your column identifier.