Table View Application

4.5.2. The table examples are built using Cocoa bindings rather than datasources (which is simpler in most cases).

It doesn’t. theDataSource is just a variable that the data is stored in, and that the datasource handlers provide to the table.

That means those datasource handlers aren’t being found in your script.

Hi Shane,

I just purchased your book and it looks like it has pretty much everything I need!

Thank you,
CQ

Thanks – and good luck!

Hi Shane,

Still working with your examples. Your examples compile correctly. But when I follow your steps in the book and build from scratch I can’t seem to get things to work.

I’m trying to build an app that has the exact functionality as Craig’s tutorial. Table View and text fields for entry that allow the user to add, update and remove from the Table View… and a way to load and save data to a file.

Very frustrating.

I’m sure it’s something simple.

Back to the drawing board.

CQ

Email me a non-working project.

For anyone lurking, the problem was not having any memory management.

Hi Shane,

I’m still trying to figure out the most elegant way to update an item within the data array.

I’m using this to add

tell theArrayController to addObjects_({{itemOne:itemOne, itemTwo:itemTwo, itemThree: itemThree}})

I’m simply using remove: action of the Array Controller to remove.

What is the best way to update an item in the array?

Also, I selected “Auto Rearrange Content” in the array controller which works great when the user selects a column to sort on. How do I setup a column to auto rearrange by default?

Any information would be greatly appreciated,
CQ

When I try changing theData which is bound to the array controller it doesn’t automatically update the view. You have to click off or on the view to see the change.

Is it better to change the array controller data instead? If so, how?

You’ll find it simpler to modify your data via the array controller. There are a range of methods: add:, addObject:, addObjects:, insertObject:atArrangedObjectIndex:, etc.

I had found that list of methods and insertObject:atArrangedObjectIndex: seems like the one. However I couldn’t figure out to implement it. I kept getting errors.

Still trying to figure out the sort. I have it working where I update the data and tell the view to update. Is there a way that the controller could sort the data automatically?

Post some code.

You have to trigger it. Try rearrangeObjects.

Hi Shane,

Thanks for the reply!

I found out how to use insertObject:atArrangedObjectIndex: in your book.

I explored two different ways to update…

With this option when you update the table row the row stays selected


theData's replaceObjectAtIndex_withObject_(myTableView's selectedRow as integer, {itemOne:itemOne, itemTwo:itemTwo, itemThree: itemThree})
myTableView's reloadData()

With this option when you update the table row the row doesn’t stays selected (which I need)


tell theArrayController to removeObjectAtArrangedObjectIndex_(myTableView's selectedRow as integer)
tell theArrayController to insertObject_atArrangedObjectIndex_({itemOne:itemOne, itemTwo:itemTwo, itemThree: itemThree}, myTableView's selectedRow as integer)

Trying to find rearrangeObjects in the controller now for sort.

I did find this code which works (but only if a sort column is selected by user)


set sortDesc to myTableView's sortDescriptors()
theData's sortUsingDescriptors_(sortDesc)
myTableView's reloadData()

I’m trying to sort the array by the key “itemOne” every time a new entry is added to the array.

I can’t figure that one out. I found a method in your book that sorts lists but it doesn’t work with either theArrayController or theData

I wonder whether it might be worth rethinking your UI a bit.

The simplest table involves just editing values in place, but sometimes you need them in separate fields. But if you bind the contents of those fields to the array controller with a Controller Key of selection and a suitable Model Key Path, you get the benefit of a separate entry area but without the need for lots of code. You just click on an entry, and the values appear in the fields; edit the fields, and the table updates.

Hi Shane,

Thanks again for the reply.

That’s an interesting idea I’ll have to play with that to find out how a new entry would be created.

I’m still trying to figure this sort thing out.

Is there a way to do the following without the user having to click on the column header?

set sortDesc to myTableView's sortDescriptors()
theData's sortUsingDescriptors_(sortDesc)
myTableView's reloadData()

Thanks,
CQ

New issue: If I sort the table by clicking the table column header and use the code below the selectedRow index doesn’t match up with the what’s in theData.


set my itemOne to itemOne of item ((myTableView's selectedRow as integer)+1) of theData

That’s right. The raw data and what’s showing in the table don’t match in order. Get the data directly from the array controller (selectedObjects()).

Clicking on a column header sets the array controller’s sortDescriptors property. Until you do that, the controller has no sortDescriptors – unless you add them using setSortDescriptors_, passing an array of NSSortDescriptors.

Shane,

Thanks! I’ll give that a try.

Also, your book is great! It has been so helpful!

CQ

What am I doing wrong?


set theDescriptor to SortDescriptorClass's sortDescriptorWithKey_ascending_("jobDate",true)
log theDescriptor -- (jobDate, ascending, compare:)
theArrayController's sortUsingDescriptors_({theDescriptor})

I get this error:
unrecognized selector sent to instance