views:

760

answers:

3

I need to have a NSTextField working with a NSStepper as being one control so that I can edit an integer value either by changing it directly on the text field or using the stepper up/down arrows.

In IB I've added both of these controls then connected NSStepper's takeIntValueFrom to NSTextField and that makes the text value to change whenever I click the stepper arrows. Problem is that if I edit the text field then click the stepper again it will forget about the value I manually edited and use the stepper's internal value.

What's the best/easiest way to have the stepper's value be updated whenever the text field value is changed?

+3  A: 

Skip the takeIntValueFrom: method. Instead, bind both views to the same property in your controller. You may also want to create a formatter and hook up the text field's formatter outlet to it.

Peter Hosey
+3  A: 

I would have a model with one integer variable, which represents the value of both controls.

In my controller, I would use one IBAction, connected to both controls, and two IBOutlets, one for each control. then I would have a method for updating outlets from model value.

IBOutlet NSStepper * stepper;
IBOutlet NSTextField * textField;

- (IBAction) controlDidChange: (id) sender
{
    [model setValue:[sender integerValue]];
    [self updateControls];
}

- (void) updateControls
{
    [stepper setIntegerValue:[model value]];
    [textField setIntegerValue:[model value]];
}

This is the principle. As said by Peter Hosey, a formatter may be useful on your text field, at least to take min and max values of stepper into account.

mouviciel
A: 

I did as Peter Hosey suggested as it seems to me the cleanest approach. Created a property in my controller:

int editValue_;
...
@property (nonatomic, readwrite) int editValue;
...
@synthesize editValue = editValue_;

then in IB for both controls in the Bindings tab I've set the "Bind to:" check box and selected my controller, then on the "Model Key Path" field set "editValue" and voilá, it worked! With just 3 lines of code and some IB editing. And if I need to change the value on my controller I use setEditValue: and the text field gets updated.

carlosb