Table View Application

Hello all,

I’m updating an old AppleScript based Xcode 2 project to Xcode 4 and I have run into a road block on how to setup a table view and connect a data source and then read/write data to file with add/update/delete buttons to modify the records.

There is an existing tutorial that has everything that I need here:
http://macscripter.net/viewtopic.php?id=30359

However, it is outdated.

Does anyone have a sample project or link to a tutorial that covers this using Xcode 4?

Any information would be greatly appreciated.

Thank you,
Mike

For some reason the linked version seems to have left out some coercions in tableView_objectValueForTableColumn_row_. Try changing it to this:

	on tableView_objectValueForTableColumn_row_(aTableView, aColumn, aRow)
		if theDataSource's |count|() as integer is equal to 0 then return 
		set ident to aColumn's identifier()
		set theRecord to theDataSource's objectAtIndex_(aRow)
		set theValue to theRecord's objectForKey_(ident)
		if ident's isEqualToString_("theStatus") as boolean then
			if theValue's intValue() as integer = 0 then
				set theValue to NSImage's imageNamed_("green")
			else
				set theValue to NSImage's imageNamed_("red")
			end if
		end if
		return theValue
	end tableView_objectValueForTableColumn_row_

Hi Shane,

Thanks for the reply. I’ll try my best to get that to work.

I’m still trying to figure out how to get everything to link up. Things are different in Xcode 4.

I remember Apple having example files as part of the developer tools release. Table view was one of the examples. It had buttons for add, remove and update records.

I really wish then had a simple source file for this.

Thank you,
CarbonQuark

Hey All,

The thing that is tripping me up the most is how to connect the table view to a data source?

I downloaded the outdated source in Craig’s tutorial and inspected the AppleScript and IB layout and I’m not seeing how the connection is made.
http://macscripter.net/viewtopic.php?id=30359

Does anyone have any idea on how this happens? I know it’s probably something simple. I have tried different connections and can’t seem to get it. All of the Xcode 4 tutorials on table views/data source are targeting iOS so they haven’t been much help.

Thanks,
CQ

You control-click on the table view, then in the HUD panel that appears you drag from the circle next to datasource across to the blue cube representing your app delegate instance.

FWIW, my book (see my sig below) comes with many example projects.

Hi Shane,

Thanks again.

I’ll check out your book. What version of Xcode are your example files built with? I’m using Xcode 4.5.2

I had already tried what you suggested.

When creating a test project I followed Craig’s video tutorial which was great.
Craig’s video:
http://allancraig.net/index.php?option=com_content&view=article&id=86:applescriptobjc-in-xcode-part-2-video&catid=41:applescriptobjc&Itemid=90

Here is my code (modified from Craig’s):


    -- Application Properties
	property timeTrackerTableView : missing value
	property timeTrackerWindow : missing value
	property jobDateTextField : missing value
	property jobNumberTextField : missing value
	property jobHoursTextField : missing value
	
    -- Application Bindings
	property jobDate : ""
	property jobNumber : ""
	property jobHours : ""
    
    -- Data Properties
	property theDataSource : {}
    
    -- Application Methods
  on awakeFromNib()
        set theDataSource to NSMutableArray's alloc()'s init()
        set theData to {{jobDate:"123", jobNumber:"123", jobHours:"123"}, {jobDate:"123", jobNumber:"123", jobHours:"123"}}
        theDataSource's addObjectsFromArray_(theData)
        timeTrackerTableView's reloadData()
  end awakeFromNib

[b]I dont understand how “dataSource” which is connected to my app delegate connects to the property “theDataSource”

In Craig’s example I couldn’t find the connection.

When I run the program the Table View doesn’t display anything[/b]

I’m also getting this error:
*** Illegal NSTableView data source. Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:

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.