objective-cxcodemacoscocoacocoa-bindings

Force Cocoa to update bound value on button click


By default Cocoa binding of NSTextFiled's value to a property only does model update when text field loses input focus.

Is there a way to force an update on, for example, form button click and not using 'Continuously Update Value'?

What have I tried.

I've created Xcode macOS Objective-C project with XIB interface.

I've laid out my MainMenu's form in the following way:

Form layout

I've added to the project the following class:

@interface Person : NSObject
@property (weak) NSString* firstName;
@property (weak) NSString* middleName;
@property (weak) NSString* lastName;
@end

and modified my AppDelegeate:

@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (strong) Person* person;
@end

Finally, I've bound my form NSTextFileds to AppDelegate's person's properties as follows:

Binding

and connected the save button action to the following method:

- (IBAction)onSave:(id)sender {
    NSLog(@"%@ %@ %@", self.person.firstName, self.person.middleName, self.person.lastName);
}

Now, when I run the application and

  1. Enter 'John' into the first text field, click second one;
  2. Enter 'Lee' into the second text field, click third one;
  3. Enter 'Hooker' into the third text field and click save button

, I got in the log John Lee (null).

This, obviously, means, that by default bound values are updated only when text field loses input focus.

So, is there a way to force Cocoa to update all form's bound values on button click?

The 'Continuously Update Value' option does the thick, but I'm going to avoid updating model on each keyboard hit.


Solution

  • The easiest way is to make sure the text fields relinquish first responder state which implies ending edit. Example:

     - (IBAction)onSave:(id)sender {
        [[sender window] makeFirstResponder:[sender window]]; // <-- this!
        NSLog(@"%@ %@ %@", self.person.firstName, self.person.middleName, self.person.lastName);
    }