NStableView Mouse Actions

Discussion in 'Mac Programming' started by kristiaand, Oct 27, 2008.

  1. kristiaand macrumors member

    Joined:
    Dec 5, 2007
    #1
    Hi lads,
    after a little but of help with an NSTableView. i have a 2 column table view and so far i am populating it with data, and its going well. i have got abit of a problem tho.

    I cannot work out how to get the info back when the user clicks a row in the TableView. I am using the following code to pickup on the return of data but when it goes to NSLog i am getting multiple entries, also when i move the mouse to another entry without clicking on it, NSLog shows that data as well.

    Code:
    - (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(int)row 
    {
    	if ([[tc identifier] isEqualToString:@"city"]) 
    	{
    		NSLog([[tableArray objectAtIndex:row] city]);
    		return [[tableArray objectAtIndex:row] city];
    		
        } 
    	else
    	{
            return [[tableArray objectAtIndex:row] nickname];
        }
    	
    }
    how do i go about just getting the data when the user clicks on a row and not when it changes row?

    the code was taken from a bigger example i had, where does the return statement just below the NSLog line put the data?
     
  2. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #2
    anyone have a suggestion on this? all i want it do is return the data in the row when i click on it.... but so far nothing.
     
  3. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #3
    I'm a bit confused. Are you trying to find the selected row? Or when the row selection changes (tableViewSelectionDidChange)?
     
  4. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #4
    Hi Sorry about that mate, i was hoping it made sense as it did in my head lol

    basically all i want todo is get the data in the row the user clicked on .

    i have a 2 column table with static data in it and when someone clicks a row i cannot work out how to get the data from the row.
     
  5. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #5
    Well tables only display the data you give it. So what you need to do is find the selected row(s) and then use that row as an index to your data array:
    Code:
    id someObject = [tableArray objectAtIndex:[tableView selectedRow]];
    If you need to find when the row changes, implement:
    Code:
    - (void)tableViewSelectionDidChange:(NSNotification *)notif {
        ...
    }
     
  6. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #6
    Cool ok so if i understand what your saying to get the data from the row that has been currently clicked on by the users i would implement the following method, and in that call i would the write the code to get the row and look at that against my array?

    Code:
    - (void)tableViewSelectionDidChange:(NSNotification *)notif {
    
    someObject = [tableArray objectAtIndex:[tableView selectedRow]];
    
    }

    if not can someone please point me in the direction of a simple to understand NStableView tutorial. its scary how complicated a visual control can be and the lack of information geared up for learners on the subject.
     
  7. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #7
    Yes that is right. Have you read Apple's documentation? They have lots of conceptual documentation and examples. NSTableView is old and there are plenty of tutorials around on it :)
     
  8. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #8
    Hi Kainjow,
    thanks for the reply, i am trying to read there docs but for someone whos just starting out with obj-c there docs tend to get a little over my head quite quickly. i can normally find what i want in there i just have no idea on how to use it.
     
  9. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #9
    ok im struggling again.. got halfway there and things are going wrong and i cannot see why.

    heres what the debugger / console shows when i click an item

    Code:
    2008-11-04 21:48:54.954 NSTableView Tutorial[613:813] [B]New York[/B]
    2008-11-04 21:48:56.457 NSTableView Tutorial[613:813] *** -[NSCFType city]: unrecognized selector sent to instance 0x16e1a0
    2008-11-04 21:48:56.458 NSTableView Tutorial[613:813] *** -[NSCFType city]: unrecognized selector sent to instance 0x16e1a0
    and this is what happens when i click in the list but not on an item.
    Code:
    Program received signal:  “EXC_BAD_ACCESS”.
    here is the code for my object, i know this is working ok as i am using this to populate the list, so it has to be the code in the selectiondidchange method.

    Code:
    @interface TableData : NSObject 
    {
    	NSString * city;
    	NSString * nickname;
    }
    
    - (NSString *)city;
    - (void)setCity:(NSString *)text;
    
    - (NSString *)nickname;
    - (void)setNickname:(NSString *)text;
    and here is the code in the TableViewSelectionDidChange method, myTable is obviously my table dataObject is just my "temp" object to hold the data that came from the tableview.

    Code:
    - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
    {
    	TableData *dataObject = [[TableData alloc] init];
    	dataObject = [tableArray objectAtIndex:[myTable selectedRow]];
    	NSLog([dataObject city]);
    	[dataObject release];
    }

    i fixed the first console errors and it seem to work however on the second click of the row in the table the program just drops into the debugger with

    Code:
    Program received signal:  “EXC_BAD_ACCESS”.
     
  10. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #10
    You don't need and shouldn't use the first and last lines above. I'll go through it line by line.
    Code:
    TableData *dataObject = [[TableData alloc] init];
    Here you are creating a TableData instance. You don't want this because you're only getting an existing object, not creating a new one. So remove that line.
    Code:
    dataObject = [tableArray objectAtIndex:[myTable selectedRow]];
    NSLog([dataObject city]);
    This is fine and is what you want.
    Code:
    [dataObject release];
    This is the main problem. Since you've reassigned dataObject to the object in your array, dataObject now points to an object that you no longer own (presumably). Therefore, by releasing the object, the object gets deallocated. The next time your table view redraws, it tries to access this same object in the array, but the object no longer exists.

    So remove the first and last line and it'll work fine.
     
  11. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #11
    Hi Kainjow,
    thanks for the advice i was worried about removing the last line incase i generated a memory leak in my program.

    as for the first line

    Code:
    TableData *dataObject = [[TableData alloc] init];
    i tried removing that and when i try to compile i get an error stating that dataObject is undeclared and first used in that function?

    the code for the object is stored in a seperate set of .m and .h files to the appcontroller code, am i right in thinking i need to add an include to the object .h file for it to work?
     
  12. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #12
    My bad. You need the declaration, just don't assign it to a new instance. So it should look something like this:
    Code:
    TableData *dataObject = [tableArray objectAtIndex:[myTable selectedRow]];
    NSLog([dataObject city]);
    And yes, you need a #import "TableData.h"
     
  13. kristiaand thread starter macrumors member

    Joined:
    Dec 5, 2007
    #13
    Kainjow,
    your a star and you must have the patience's of a saint dealing with people like me on here all day.

    Thats got my program working fine now, i even worked out how to get data back from a multi column TableView thanks to you :) and ive put error checking in to make sure that if someone clicks on the tableview but not a row it does nothing.

    i know that dont seem like a lot but to me its a good accomplishment

    thanks again.
     

Share This Page