Search code examples
macoscocoansoutlineview

Do I really need to implement outlineView(_:objectForValue:byItem:)? How?


I want to implement an outline view without using Cocoa bindings.

I checked out this tutorial among some others and none of them makes use of the data source method

optional func outlineView(_ outlineView: NSOutlineView, 
             objectValueFor tableColumn: NSTableColumn?, 
                            byItem item: Any?) -> Any?

However, Apple's documentation states:

While this method is marked as @optional in the protocol, you must implement this method if you are not providing the data for the outline view using Cocoa bindings.

For the tutorials, it seems to be working without that method. But what is it good for then and how is it supposed to be used?

(What confuses me is that it reads like it's supposed to return a data object, but it gets passed an item parameter as an input which is a data object in my understanding.)


Solution

  • NSTableView/NSOutlineView and its documentation are a mess.

    The byItem parameter of outlineView(_:objectForValue:byItem:) is the object represented by the row and the return value is the object represented by the cell. Compare tableView(_:objectValueFor:row:) the return value is

    An item in the data source in the specified table column of the view.

    See also the objectValue property of NSTableCellView

    The object that represents the cell data.

    The objectValue is automatically set by the table when using bindings or is the object returned by the NSTableViewDataSource protocol method tableView(_:objectValueFor:row:).

    In reality when binding the table view content, objectValue is the row object.

    NSOutlineView.h says about outlineView(_:objectValueFor:byItem:):

    NOTE: this method is optional for the View Based OutlineView.

    Apple's documentation

    While this method is marked as @optional in the protocol, you must implement this method if you are not providing the data for the outline view using Cocoa bindings.

    is valid for cell based outline views only.

    If you set the value of the controls in the cells in outlineView(_:viewFor:item:) then you don't have to implement outlineView(_:objectValueFor:byItem:).

    Implement outlineView(_:objectValueFor:byItem:) if you want to use the objectValue property of the cell view. For example when binding the value of the controls in the cell and not binding the content of the outline view.

    See also Populating a Table View Programmatically