Getting started with NSTableView

Discussion in 'Mac Programming' started by Thomas Harte, Jan 20, 2006.

  1. macrumors 6502

    #1
    I am someone with past experience of C++ and MFC who is trying to get started with Objective-C and Cocoa development. I have some books ordered to help me, but they haven't turned up yet, so I'm stuck trying to figure stuff out from the XCode help and http://developer.apple.com/documentation/Cocoa/. I did the Currency Converter tutorial and now am sort of wandering the API around aimlessly.

    Today I am trying to make a decent stab at a NSTableView. I have added an NSTableView to my .nib, and set my controller as a dataSource. I have added the two methods numberOfRowsInTableView and what I guess could be called objectValueForTableColumn to my controller and I am able to populate the NSTableView by returning sensible results from those two methods. I am returning NSStrings for objectValueForTableColumn.

    I have two questions. Firstly, what is the "correct" way to use the value passed as an (NSTableColumn *) to objectValueForTableColumn? At the minute I'm just doing [[tableColumn headerCell] stringValue] and comparing that to what I know are the column headers. That works, but strikes me as a very roundabout way of doing things and prone to localisation problems.

    Secondly, how do I stop my NSTableView from being editable? What I really want is to receive a message on a row double click that will be responded to by actions in my model class. I have not implemented setObjectValue, which I thought would be enough to prevent editing but it doesn't seem to be. I want dragging and dropping so I need to implement validateDrop and forDraggedRowsWithIndexes, but I haven't done that yet.

    Thanks in advance, and sorry for asking what are probably very basic questions that will have easy and easily discoverable answers once I have books.
     
  2. Administrator

    HexMonkey

    Staff Member

    #2
    You could use [tableColumn identifier] instead. The identifier is set in Interface Builder in the same place as the header title, and it needn't be localised.

    To prevent the cells from being editable, select each table column in Interface Builder and uncheck the "Editable" attribute in the inspector.

    To handle a double click, add the following code in your awakeFromNib method:
    Code:
    [tableView setTarget:self];
    [tableView setDoubleAction:@selector(doubleClickInTable:)];
    The doubleClickInTable method (call it anything you want) would be implemented as follows:

    Code:
    - (void)doubleClickInTable:(id)sender
    {
    	int rowIndex = [sender selectedRow]; //Use selectedRowIndexes if you're supporting multiple selection
    	
    	//Handle the double click
    }
     
  3. Moderator

    robbieduncan

    Staff Member

    #3
    I would recommend looking at Bindings instead of a datasource but we'll skip that for now!

    Set a tag for each header in Interface Builder and then use [tableColumn tag]==0 (or whatever the tag value is: they are ints). The tag won't change on localization. (and int comparisons are cheaper than NSString). Edit: beaten to it and with the correct answer too: columns don't seem to have tags :(

    Per column (double click on the column until it highlights) there is an editable attribute in Interface Builder. Use that to stop it being editable :D

    Any more questions?
     
  4. macrumors 6502

    #4
    I have implemented it exactly as you suggest, but I seem to be getting single clicks as well. Is there anything I can do about that?
    We'll have to as I haven't yet figured out anything whatsoever about Bindings! I'll make a note to check that topic out as soon as I have some nice tangible documentation though.
    I've gone with naming my columns as numbers and the following:

    int column = [[tableColumn identifier] UTF8String][0] - '0';

    I'm only planning on three columns, so I don't have to worry about moving on from '9' to ';' or anything like that.
     
  5. Moderator

    robbieduncan

    Staff Member

    #5
    Start off with the Apple Documentation.

    That will probably leave you dazed and confused so then take a look at a nice easy introductory tutorial.

    Now you are probably beginning to get an understanding and some clear examples will help.
     
  6. Administrator

    HexMonkey

    Staff Member

    #6
    That's strange, the only way that happens for me is if the table view also has an action (as well as a double action). Try adding the code:
    Code:
    [tableView setAction:nil];
    to the end of your awakeFromNib method and see if it fixes it. If it does, check your connections in Interface Builder and make sure you're not calling setAction elsewhere in your code.
     
  7. macrumors 6502

    #7
    Although I am building on 10.4, I want to retain compatibility with 10.2 and 10.3 so I guess I can't use bindings in this project. It's actually really trivial on the code side and something I'm sure anyone with good Cocoa sense could knock up in half an afternoon. If it gets too much for me I'll just go back to the tutorials rather than asking stupid questions here...
    Interestingly that stopped the response to double clicks, so I guess I must have a connection set up in Interface Builder that I've just forgotten about. I can't find anything, but I'm still not 100% confident with that corner of the developer tools having just been using XCode to do the normal platform neutral stuff with SDL and so on until now.

    Anyway, I just wanted to say thanks to both of you for the help. Thanks!
     

Share This Page