0
votes

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?

1
If the state of a button is bound to a property in Interface Builder, you don't need an outlet. The value of the property is updated dynamically and also the appropriate KVO methods are called.vadian
I'm not sure I've binded the state but the "Value" of my NSButton: Bind to: File's Owner Controller Key: <empty> Model Key Path: self.isThisButtonActiveTom
My bad, of course it's value. And self in the key path is not needed.vadian
Everything works well when I press my button. Problem is when I want to revert programmatically in my test.Tom

1 Answers

2
votes

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.