TableView: shouldEditTableColumn: string: for view based NSTableView

According to Apple's documentation[NSTableViewDelegate tableView:shouldEditTableColumn:row:]

, this method is only valid for NSCell-based table views. What is its equivalent for view-based table views? I would like to replace the default inline editing with custom editing.

+3


source to share


2 answers


There is really no need for this delegate method with view based views.

In this case, you need to create, for example, some subclass of NSView. There may also be a nib file.

Let's say you have a class named CustomCellView that has multiple points. 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 a nib file and plug in your sockets. Your NSTableView class needs to have some reusable initialization code.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 not exists - we'll set the data in NSTableViewDataSource method
  if (view) // if it exists
    [view setCellEditable:editable];
}

      

+2


source


Commenting on Astoria's approach:

The inconvenient "problem" of having to change the editableness of a text box whenever the editableness of the model changes is that you need to "actively" track the editableness of the model and update the editableness of the text box.

In contrast, the cell-based table view delegate's approach diverts attention to editable until the user tries to make an edit, at which point the delegate simply returns whether the model can be edited or not. There is much less customization and less room for error. (for example, depending on how you control / respond to editable in the model, you might skip the change, and now the user might incorrectly edit or edit this field.)

So another approach is to recreate the delegate definition of editable at the time the user tries to edit. To do this, you must subclass NSTextField

, override "correct place", ask for a delegate, and enable or disable editing.



The "right spot" seems to override acceptsFirstResponder

and return NO.

- (BOOL)acceptsFirstResponder
{
    BOOL accepts = [super acceptsFirstResponder];

    if (accepts) {
        if ([self.delegate respondsToSelector:@selector(textFieldShouldBecomeEditable:)]) {
            accepts = [self.delegate textFieldShouldBecomeEditable:self];
        }
    }

    return accepts;
}

      

With the above, as long as the field editable

is YES, the delegate is called to finalize it.

Depending on your application, this may be more desirable because monitoring changes in model edits is not direct. However, it is generally best to use the standard approach to just set the field property editable

.

+1


source







All Articles