Search code examples
objective-ccocoanstableview

tableView:shouldEditTableColumn:row: for view-based NSTableView


According to Apple's documentation on [NSTableViewDelegate tableView:shouldEditTableColumn:row:], "this method is only valid for NSCell-based table views". What's its equivalent for view-based table views? I would like to replace the default inline-editing with a custom editing experience.


Solution

  • There's actually no need in this delegate method with view-based table views.

    In that case you need to create, for example, some NSView-subclass. There may be nib-file too.

    Let's say, you have a class named CustomCellView having some outlets. CustomCellView.h file

    #define kCustomCellViewReusableIdentifier @"kCustomCellViewReusableIdentifier" // NSTableView reuses cell views
    
    @interface CustomCellView : NSView
    
    @property (weak) IBOutlet NSImageView *imageView;
    @property (weak) IBOutlet NSTextField *textField;
    
    - (void)setCellEditable:(BOOL)editable;
    
    @end
    

    Here's your CustomCellView.m file

    @implementation CustomCellView
    
    - (void)awakeFromNib
    {
      // paste your ui initializing code here
    }
    
    - (void)prepareForReuse
    {
      // this method will call each time cell reuses
    }
    
    - (void)setCellEditable:(BOOL)editable
    {
      [self.textField setEditable:editable];
      // some other code
    }
    
    @end
    

    Don't forget to create nib-file and connect your outlets. Your NSTableView owner class must have some initializing code for reusing. MyTableViewController.m

    - (void)initUI
    {
      NSString *nibName = NSStringFromClass([CustomCellView class]);
      [self.tableView registerNib:[[NSNib alloc] initWithNibNamed:nibName bundle:nil]
                     forIdentifier:kCustomCellViewReusableIdentifier];
    }
    
    #pragma mark - table view data source methods
    
    - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
       CustomCellView *view=[tableView makeViewWithIdentifier:kCustomCellViewReusableIdentifier owner:nil];
       [view setCellEditable:someCondition]; // 
       return view;
    }
    
    #pragma mark - operations
    
    - (void)setViewAtColumn:(NSTableColumn *)tableColumn row:(NSInteger)row editable:(BOOL)editable
    {
      CustomCellView *view=[self.tableView viewAtColumn:tableColumn row:row makeIfNecessary:NO]; //no need to create it if it's not exists - we'll set the data in NSTableViewDataSource method
      if (view) // if it's exists
        [view setCellEditable:editable];
    }