How do I set Cocoa NSLevelIndicatorCell values?

I have a tableview. One of the columns in the tableview uses an NSLevelIndicatorCell.

I want to be able to allow the user to edit the warn and critical values for the level indicator such that when they enter a value into a a "warning level" textbox, it changes the warn value of the level indicators being displayed in ALL of the tableview's rows.

I am very much a newbie with Objective-C so all I can figure out so far is that I must need a delegate method to watch the textbox BUT if I succeed in doing that, how on earth do I send the new value to the particular tableview column so that the update happens to ALL of the rows (i.e. how do I send what message to the tableview and target a cell within a column within a tableview)?

Here is the code to the solution I came up with should anyone need it.

- (IBAction)setWarningLevel:(id)sender {
    double v;
    NSScanner *ns = [NSScanner scannerWithString:[warnLevel stringValue]];
    [ns scanDouble:&v];
    [levelIndicator setWarningValue:v];
13.10.2009 19:19:57
Probably a bit much - have a look at my answer for a simpler way.
Abizern 14.10.2009 04:36:42

This is a textbook case for using Cocoa bindings. Just bind the value of the text field to the NSLevelIndicatorCell in your table view (do that in Interface Builder). The updates should happen automagically.

I think it should apply for all the cells in the table view if you apply the binding to the cell in IB. However if it doesn't, you will need to write a couple lines of code that set up the binding every time a new row in the table is created. That link above will explain everything in detail, but basically you will be setting up a Key-Value Observer relationship in code between the text field and the instance of the level indicator in the row being created.

13.10.2009 19:42:44
Thanks for your quick help. While I was waiting, hopefully for a reply, I managed to figure it out myself (I am still in shock that I figured it out - I have only been coding Objective-C for 2 days). And yes, it DOES automagically apply to all rows! Here is my solution (in case it helps anyone): - (IBAction)setWarningLevel:(id)sender{ double v; NSScanner *ns = [NSScanner scannerWithString:[warnLevel stringValue]]; [ns scanDouble:&v]; [levelIndicator setWarningValue:v]; }
Steve 13.10.2009 21:34:44
Hey, you might want to add your solution to your question itself since no one can read that unformatted mess of code you put in your comment. =)
Marc W 13.10.2009 22:18:48

I think you may have overdone it.

NSTextField subclasses NSControl, so you need to look in the docs for NSControl for a useful function.

Try re-writing it like this; assuming you're taking the value from a warnLevel textfield.

- (IBAction)setWarningLevel:(id)sender {
    double v = [warnLevel doubleValue];
    [levelIndicator setWarningValue:v];

Although this is usually shortened to this;

- (IBAction)setWarningLevel:(id)sender {
    [levelIndicator setWarningValue:[warnLevel doubleValue]];

You should probably have some validation that the textfield has a valid number. If you're only choosing a couple of numbers have a look at using a stepper control.

Usually, with Cocoa, if you feel like you're jumping through too many hoops, there is sometimes an easier way.

Usually ;-)

14.10.2009 05:06:49
Thanks! Definitely an improvement. I am still in my learning curve with Objective-C (I only just started working with it last Sunday) and it is always a big chore to learn what is available in a new language (i.e. I know what I want to do, I know how I would do it in C or Pascal or PHP but what the heck does Objective-C call it?). I'll get there eventually!!
Steve 15.10.2009 18:12:48