Search code examples
objective-ccocoacocoa-bindingsnsbutton

Change NSButton status and the binding value programmatically


I have several NSButtons (Type On/Off), with an action set (oneButtonHasBeenPressed:), and with value binded to booleans (self.isThisButtonActive1, self.isThisButtonActive2, self.isThisButtonActive3 ...).

As I have several buttons, my goal is to be generic and not declare several IBOutlet properties on NSButtons, or several actions, only keeping booleans.

I have a problem to reverse the status of the NSButton if a test fails after pressing the button and thus the boolean associated.

- (IBAction)oneButtonHasBeenPressed:(id)sender {

    NSButton *button = (NSButton*)sender;
    // At this point, button state has already changed by IB

    if (testIsNotOk) {

       // Not ok as it goes in an infinite loop in oneButtonHasBeenPressed, but it propagates correctly KVO
       // [button performClick:nil];

       // This revert the state of my button correctly
       button.state = !button.state;

       // Now I need to change my boolean binded to this NSButton,
       // Idea is: self.isThisButtonActive = !self.isThisButtonActive
       // But I have several buttons and several booleans and can't easily link each buttons to the booleans while keeping generic (?)

       // [button didChangeValueForKey:@"value"];    // KO
       // [button didChangeValueForKey:@"state"];    // KO
    }
}

How can I change the status of my button, and then propagate the change of my boolean binded to my NSButton value?


Solution

  • If you don't want to use outlets, create an action for each button or use the tag of the button then you can get the key from the binding.

    NSDictionary *dictionary = [sender infoForBinding:NSValueBinding];
    id object = [dictionary objectForKey:NSObservedObjectKey];
    NSString *keyPath = [dictionary objectForKey:NSObservedKeyPathKey];
    if (object && keyPath)
        [object setValue:@NO forKeyPath:keyPath];
    

    If you set the value, you don't have to set the state of the button.