[MacRuby-devel] HotCocoa table_view and the doubleAction

Brian Chapados chapbr at gmail.com
Wed Apr 1 11:07:48 PDT 2009


You might have already figured this out, but in case it helps...

Be careful not to confuse the TableView delegate with the DataSource delegate.
Check out the TableView programming guide:
http://developer.apple.com/documentation/Cocoa/Conceptual/TableView/TableView.html

You can use two different sets of delegate messages to customize an
NSTableView.  The datasource delegate methods get called in order to
populate the table with data. The TableView delegate methods get
called in response to user-generated events.

The DataSource informal protocol:
http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSTableDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/cat/NSTableDataSource

delegate methods specific for a TableView:
http://developer.apple.com/documentation/Cocoa/Conceptual/TableView/Tasks/UsingTableDelegate.html#//apple_ref/doc/uid/20000116-CJBDHFIC

Your tableview delegate can also respond to delegate messages for
NSControl and NSView (its superclasses).

In your list below,
> #is not delegated to
>   def tableView(tv, setObjectValue:anObject, forTableColumn:col, row:row)
>     NSLog("tableView setObject")
>     #edit data here
>   end
> #is not delegated to
>   def numberOfRowsInTableView(tv)
>     NSLog("numberOfRowsInTableView")
>     0 #test 0
>   end
> #is not delegated to
>   def tableView(tv, objectValueForTableColumn:col, row:row)
>     NSLog("objectValueForTableColumn")
>     val = "richard"
>   end

These methods are sent to the 'dataSource' delegate, not the
'delegate' (view delegate).  In order for your dataSource delegate
methods to be called, you need to either:

1. Define the methods in a separate class, and assign an instance of
that class as:
@tableView.dataSource = myDataSource

2. Define the methods in your TableView Controller class, set the
dataSource delegate to self:
@tableView.dataSource = self

You _must_ set the tableView delegate in order to receive the
messages, even if you have everything in one class and you just want
to set them to 'self'.

For simple cases, you can implement both the 'dataSource' and view
'delegate' classes in your TableView controller and set both delegates
to self.  For an example of this, see the FlickrDemo example app in
macruby-examples dir.

Also, since it was mentioned, you should be able to leave the 'target'
property unset (or set it to nil).  In cocoa, nil targeted actions do
_not_ go into the void.  Instead, they sent are passed along the
responder chain so that the next appropriate control can handle the
message. This is useful for when you want to the same action to be
performed as a result of different inputs (i.e. menu, button or click
in row, ect..).  You can just define the action methods in a class
that is part of the responder chain and send a nil targeted actions
from your controls.

There is must-listen Mac-Developer Network podcast interview with
Aaron Hillegass on the Responder Chain:
http://www.mac-developer-network.com/shows/podcasts/lnc/lnc009/

Brian

2009/4/1 John Shea <johnmacshea at gmail.com>:
> Hi Dave,
> thanks for your answer.
>
> On Apr 1, 2009, at 14:39 , Dave Baldwin wrote:
>
> I haven't had any problems using delegate methods. For example I do:
> @tableView.delegate = self
> and define a delegate method:
> def tableView (table, shouldEditTableColumn: c, row: r)
> false
> end
>
> Thats the first thing I tried - but for the tableView(table, setObjectValue
> .. method which was not delegated to.
> Unfortunately as it was the first one i tried (because i wanted to edit
> table fields) -  that sent me on a wild goose chase trying to figure out why
> the delegate was not working as it was in all of my non-hotcocoa code.
> So thanks for pointing out that some of them are actually delegated to.
> For me:
>
>   #works
>   def controlTextDidChange(notification)
>       NSLog("controlTextDidChange #{notification.object}")
>       NSLog(@mv_table_view.selectedRow.to_s)
>   end
>
>   #works
>   def tableView(tv, willDisplayCell:cell, forTableColumn:col, row:the_row)
>    NSLog("willDisplayCell")
>   end
>   #works
>   def tableViewSelectionDidChange(notification)
>     NSLog("tableViewSelectionDidChange")
>   end
> #is not delegated to
>   def tableView(tv, setObjectValue:anObject, forTableColumn:col, row:row)
>     NSLog("tableView setObject")
>     #edit data here
>   end
> #is not delegated to
>   def numberOfRowsInTableView(tv)
>     NSLog("numberOfRowsInTableView")
>     0 #test 0
>   end
> #is not delegated to
>   def tableView(tv, objectValueForTableColumn:col, row:row)
>     NSLog("objectValueForTableColumn")
>     val = "richard"
>   end
>
> I could probably do a work around with controlTextDidChange - but it seems a
> bit dodgy.
> Or another option would be to edit not within the table, but in another
> form.
> I suppose there is some simple explanation - but I am missing it for the
> moment.
> Cheers,
> J
>
>
>
>
>
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
>
>


More information about the MacRuby-devel mailing list