Search code examples
cocoacore-datansarraycontroller

NSArrayController 'Add' function now causes saved NSTableView listed entries to temporarily lose focus


I have a few long functioning (Core Data) apps. built on an OSX (10.13.6) machine with an older version of Xcode. I customize an arrayController 'add' method to auto-insert the current date as newObject and the second adjacent column cell picks up a focus ring and is prepared for input. All works as expected for years until I attempt to run the apps. on a newer machine running Ventura (13.6.3). Now when initiating the 'add' function all the previously saved/listed entries in the table lose focus. They are sort of greyed out. Focus is restored by clicking on each entry or scrolling through via keyboard. Note if I move the [makeFirstResponder] ref. to the bottom of the code block - all listed data retains focus when initiating 'add'. However I lose the expected focus ring appearing for the cell adjacent to the date cell. In this case the new/added entry line is entirely selected. Not what I'm looking for. Anyway - any insight on how to get my implementation to work with current versions of Mac OS as it has in the past?

     [mWindow makeFirstResponder:table1];
     id newObject = [BatchController newObject];
     [BatchController insertObject:newObject atArrangedObjectIndex:0];
     [newObject setValue:[NSDate date] forKey:@"date"];
     [table1 editColumn:1 row:0 withEvent:nil select:YES];
 
     [search setStringValue: @""];
     [BatchController setFilterPredicate: nil];

enter image description here


Solution

  • The cell-based NSTableView draws all cells in placeholder style when an empty cell is edited. Hacky workaround: subclass NSTextFieldCell and override private method _effectiveContentStyleForCellInView:. As a side effect, a placeholder string is drawn as normal content.

    MyTableTextFieldCell.h:

    @interface MyTableTextFieldCell : NSTextFieldCell
    
    @end
    

    MyTableTextFieldCell.m:

    /* bugfix, cell-based NSTableView, edit empty cell -> all cells draw as placeholder */
    
    @interface NSTextFieldCell(MyTableTextFieldCell)
    
    - (id)_effectiveContentStyleForCellInView:(NSView *)view;
    
    @end
    
    @implementation MyTableTextFieldCell
    
    - (id)_effectiveContentStyleForCellInView:(NSView *)view {
        id result = [super _effectiveContentStyleForCellInView:view];
        [result setValue:@0 forKey:@"state"];
        return result;
    }
    

    Change the class of all text cells in the table view in IB to this subclass.