Array controller not rearranging…

Hello,

In a little test application, I have a simple mutable array (theList) controlled by an array controller (theController). This controller has its “arranged objects” array bound to a table view column.

  • (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.theList=[[NSMutableArray alloc] initWithObjects: nil];
    }

I populate the array with random numbers by clicking a button:

  • (IBAction) click: (id) sender {
    NSNumber *anObj;
    anObj = [NSNumber numberWithInt:(random()%100+1)];
    [theController addObject:anObj];
    [theController rearrangeObjects];
    }

The problem is: the Controller does not rearrange the array, until I click on the column header. Then it rearranges correctly each time I press the button (I don’t have to click on the header anymore).

I set the controller to “prepare contents”; I set it to “auto rearrange contents”. I have told him to rearrange objects. What am I forgetting to get my column sorted?

Thanks!

Hi,

an object in a table view should be always a key/value compliant object like a dictionary or a custom class object.
Then you could set the sort descriptor explicitly in the awakeFromNib method.
Bind the column to the key number and enable “Auto Rearrange Content” in the array controller.
The awakeFromNib method is preferable for changing UI element settings

Two notes:
¢ To initialize an array for a property, the convenience method is sufficient.
¢ As random() returns a long integer, use the appropriate init method


- (void)awakeFromNib
{
   [theController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"number" ascending:YES]]]; 
    self.theList = [NSMutableArray array];
}

- (IBAction)click:(id)sender
{
    NSNumber *anObj;
    anObj = [NSNumber numberWithLong:(random()%100+1)];
    [theController addObject:[NSDictionary dictionaryWithObject:anObj forKey:@"number"]];
}


Stefan,

Is there a good reason to use a dictionary when you have a one column table? I’ve made them in the past with just a simple array like Bernard did here, and it seems to work fine. In this case you can do what he wants by passing nil for the key in sortDescriptorWithKey:ascending: Is there a down side to this approach?

Bernard,

What you missed is this statement in the arrangeObjects method description (which is called by rearrangeObjects as it says in that method’s description):

“An array containing objects filtered using the receiver’s filter predicate (see filterPredicate) and sorted according to the receiver’s sortDescriptors.”

Ric

For a single column it’s indeed not necessary to use a key/value object.

Stefan,

Thank you for your corrections and the description for multicolumn bindings (I used this with the keys/values ASOC records), but I forgot to mention that I’m using a single column, my mistake. So no need of a key, even if I prefer to work with keys now.

Ric,

I know I’m missing something here. You mentioned that I could use the default sort descriptor in IB: no key (I suppose it’s equivalent to NIL) and ascending order.

So I replaced all my methods and types as Stefan wisely pointed out (with random numbers over 32767 I would have negative numbers or maybe an error). I also removed the rearrangeObjects message. But.

Curse. Always the same behavior. So I’m still missing something (same thing occurs in ASOC, I have checked). Not an ObjC beginner error, then, but just a. beginner error :confused: , but where?

Regards,

my code works, this is the one-column version


- (void)awakeFromNib
{
   [theController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:nil ascending:YES]]]; 
    self.theList = [NSMutableArray array];
}

- (IBAction)click:(id)sender
{
    NSNumber *anObj;
    anObj = [NSNumber numberWithLong:(random()%100+1)];
    [theController addObject:anObj];
}


Mine too. Sorry, I thought I could rely on the default sorter. So one have to set them explicitly?

Yes, you have to set them explicitly – there is no default descriptor, I didn’t mean to imply that with my post, only that rearrangeObjects depends on the sort descriptors that you need to supply.

Ric

So how are the objects sorted (and stayed sorted) when you click on the header of the column?

setting the sort descriptor programmatically is actually the same as clicking on the column header.
@selector(compare:) and direction ascending is the default descriptor.

btw: another advantage of using a key/value object is to be able to change the sort direction by clicking on the column header

And to change KVO/KVC programmatically?

By the way, about lists and records vs arrays and dictionaries, I found a noticeable difference:

ASOC

Objective-C

Well. Well, well, well. :confused:

Thanks again for the books references. Hillegass’ book is the equivalent of Shane Stanley’s book on ASOC: Clear, educational and reassuring.
Regards,