Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa: Avoiding 'Updates Continuously' in control binds

I have several panels that contain NSTextField controls bound to properties within the File's Owner object. If the user edits a field and then presses Tab, to move to the next field, it works as expected. However if the user doesn't press Tab and just presses the OK button, the new value is not set in the File's Owner object.

In order to workaround this I have set Updates Continuously in the binding, but this must be expensive (EDIT: or at least it's inelegant).

Is there a way to force the bind update when the OK button is pressed rather than using Updates Continuously?

like image 907
trojanfoe Avatar asked Jun 28 '26 10:06

trojanfoe


2 Answers

You're right that you don't need to use the continuously updates value option.

If you're using bindings (which you are), then what you should be doing is calling the -commitEditing method of the NSController subclass that's managing the binding. You'd normally do this in your method that closes the sheet that you're displaying.

-commitEditing tells the controller to finish editing in the active control and commit the current edits to the bound object.

It's a good idea to call this whenever you are performing a persistence operation such as a save.

like image 75
Rob Keniger Avatar answered Jun 30 '26 12:06

Rob Keniger


The solution to this is to 'end editing' in the action method that gets called by the OK button. As the pane is a subclass of NSWindowController, the NSWindow is easily accessible, however in your code you might have to get the NSWindow via a control you have bound to the controller; for example NSWindow *window = [_someControl window].

Below is the implementation of my okPressed action method.

In summary I believe this is a better solution to setting Updated Continuously in the bound controls.

- (IBAction)okPressed:(id)sender
{
    NSWindow *window = [self window];
    BOOL editingEnded = [window makeFirstResponder:window];
    if (!editingEnded)
    {
        logwrn(@"Unable to end editing");
        return;
    }

    if (_delegateRespondsToEditComplete)
    {
        [_delegate detailsEditComplete:&_mydetails];
    }
}
like image 32
trojanfoe Avatar answered Jun 30 '26 14:06

trojanfoe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!