What are the reasons for subclassing NSArrayController?
Asked Answered
S

5

15

I am trying to improve my KVC/KVO/Cocoa-Bindings-fu and was wondering what could be the reasons to subclass the NSArrayController?

Saucy answered 3/4, 2011 at 6:28 Comment(2)
Too bad there aren't more replies; it's an interesting question, and my silly little trick barely scratches the surface of the subject.Kentish
Indeed. I'll try sharing online...Saucy
M
17

I have a custom NSArrayController subclass that perform a whole bunch of task. I chose to implement these things there because I can then enjoy the full comfort of bindings and stuff. Here's what I use this now for:

  • Sometimes some items must be hidden and some must be shown
  • I perform custom sorting (i.e. grouping) in the controller
  • It is fed by the items of a different kind than it returns (get items, returns item nodes - dummy objects that forward most stuff)
  • I also use it to hold the filter criteria and search options currently on display
  • In addition, I added NSTableView delegate and data source support that allows drag & drop implementation right in the controller
  • I also customize tool tips for the cell in there

Yeah, and so on. Basically this all boils down to this essence: subclass NSArrayController if you want different data out than you put in

Max

Macrocosm answered 7/5, 2011 at 1:7 Comment(2)
Informative list Max; what are you doing to customize tooltips?Lisp
@Mike Abdullah: It's part of the NSTableView delegate, where I just implement this method: tableView:toolTipForCell:rect:tableColumn:row:mouseLocation:Macrocosm
K
9

One thing I like to do when using an array controller with a table view is to override add: to post a notification so that the new item is selected and open for editing right away. I actually posted this over at CocoaDev a while ago:

// Subclass of NSArrayController

- (void)awakeFromNib
{
    [[NSNotificationCenter defaultCenter] addObserver: self 
                                             selector: @selector(objectAdded:) 
                                                 name: @"Object Added" 
                                               object: self]
}

- (void)add: (id)sender
{
    [super add: sender]
    NSNotification * note = [NSNotification 
                                notificationWithName: @"Object Added" 
                                              object: self]
    // The add method doesn't really take effect until this run loop ends,
    // (see NSArrayController docs) so the notification needs 
    // to wait to post. Thus, enqueue with NSPostWhenIdle
    [[NSNotificationQueue defaultQueue] enqueueNotification: note
                                               postingStyle: NSPostWhenIdle]
}

- (void)objectAdded: (NSNotification *)note
{
    // when the notification finally arrives, tell the table to edit
    [[self contentTable] editColumn:0 
                                    row:[self selectionIndex] 
                              withEvent:nil 
                                 select:YES]
}

Of course it's possible to do similar with a controller that's not an NSArrayController subclass; this is just the first way I figured out.

Kentish answered 3/4, 2011 at 9:5 Comment(1)
You could override -addObject: rather than -add: and post the notification normallyLisp
D
1

I have an app that needs to set a hidden file name when the user adds an object - the add method in a custom ArrayController class is just the place to do this.

Edit - Actually, re-reading my Hillegas, overriding newObject is the better way. It still requires a subclass of NSArrayController though.

Dodder answered 6/4, 2011 at 12:23 Comment(0)
H
0

I subclassed array controller to return the desired object upon invoking -(id)newObject;

Normally you have .h & .m file for each class in your project and array controller creates specific object based on the name of the class by reading those files.

But when you have only one .h .m file or a class (eg:Entity) which can return any object (eg: employee,customer, by reading stored modal definitions) based on your neeed, you have to subclass arraycontroller because class name remains same (Entity) whether you need employee object or customer object.

Haggerty answered 28/6, 2013 at 8:56 Comment(0)
F
0

I use a subclass of NSArrayController to name the Undo/Redo actions for adding and removing objects in my Core Data application.
(It was not my own idea, the credit goes to user @MikeD who answered my question on this matter.)

Override the - newObject method.

- (id)newObject
{
    id newObj = [super newObject];

    NSUndoManager *undoManager = [[[NSApp delegate] window] undoManager];
    [undoManager setActionName:@"Add *insert custom name*"];

    return newObj;
}

Also the - remove:sender method.

- (void)remove:(id)sender
{
    [super remove:sender];

    NSUndoManager *undoManager = [[[NSApp delegate] window] undoManager];
    [undoManager setActionName:@"Remove *insert custom name*"];
}
Forfar answered 5/6, 2014 at 11:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.