5

I use a view-based NSOutlineView to display and select hierarchically structured items for a scientific application.

view-based NSOutlineView

Each row in the outline column represents an item, signified by an item-specific icon (all the same in the picture), a checkbox that shows if the item is selected, and the name of the item. I need the icon, the checkbox and the name to appear in the same cell, hence I am using a view-based NSOutlineView.

I have implemented the NSOutlineViewDataSource protocol to supply data to the the outline view.

The method outlineView:objectValueForTableColumn:byItem: supplies a custom object that has the properties BOOL selected and NSString *name.

My custom table cell view in IB is composed as follows:

view-based NSOutlineView in IB

I bound the check box value to objectValue.selected and the label value to objectValue.name.

As I hoped, the outline view displays nicely the name and selection state supplied by the objectValue.

However, if I change the state of the check box, the method outlineView:setObjectValue:forTableColumn:byItem: that is defined in the NSOutlineViewDataSource protocol is not triggered in my dataSource to supply the newly changed object value. Note that if I don't use a custom view for the cell this works.

I checked whether the table cell view's objectValue.selected actually gets changed when clicking the check box by inserting an NSLog statement into the setSelected method of the object that is passed as objectValue. The selected member changes state correctly.

How do I propagate the change of the objectValue back to my dataSource's model? I have checked the NSOutlineView's delegate methods, but can't find a way to signal that the cell view's objectValue was changed by my check box (i.e., that the cell view has "ended editing"). Is there some other fundamental point I am missing?

timo
  • 79
  • 6
  • I noticed you're working with data source methods, but also that you used the word "bound." Are you using Cocoa Bindings? If so, how exactly are you binding the check box to that object? – paulmelnikow Feb 22 '12 at 23:33
  • Also, am I correct that `outlineView:objectValueForTableColumn:byItem:` returns a pointer to your model object? I suggest checking whether `-copyWithZone:` is being called on it. If so, the view is creating a second instance of the model object, which might help explain why the change to the check box doesn't propagate back to your original instance of the model object. – paulmelnikow Feb 22 '12 at 23:34
  • Did you figure this out? I'm having the same problem. – pickwick Mar 14 '12 at 20:49

2 Answers2

2

setObjectValue doesnt work for view based ones:

from header::

/* View Based OutlineView: This method is not applicable.
 */
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item;
Daij-Djan
  • 49,552
  • 17
  • 113
  • 135
0

I was able to solve this problem by creating a subclass of NSTableCellView, making it the delegate of the contained NXTextField, and using the edited value to update NSTableCellView's object value.

class CategoryNameTableViewCell : NSTableCellView, NSTextFieldDelegate {

    func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
        guard var category = self.objectValue as! Category? else {
            Swift.print("Tried to edit category cell with no object!")
            return false
        }
        category.name = control.stringValue
        category.saveChanges()
        return true
    }

}
Doug Knowles
  • 873
  • 1
  • 8
  • 14