objective-cmacosnspredicatenspredicateeditor

NSPredicateEditor callBack when NSPredicate added or changed


I am on XCode 9.3, objective-c, OSX not iOS.

I use an NSPredicateEditor in my app which works fine so far. However i have a view that shall update its content with the predicates set in the editor (basically the view shows filtered arrays).

Currently i have a "Refresh" button the user needs to hit to update the view once he changes something in the editor.

I was wondering if there's a way to trigger my method to update the view automatically when a predicateRow is added OR changed?

I tried to add an observer to the NSPredicateEditor.objectValue - but i don't receive a notification.

- (void)viewWillAppear {
    [self.predicateEditor.objectValue addObserver:self selector:@selector(predicateChangedByUser:) name:@"Test" object:nil];
}

- (void)predicateChangedByUser:(NSNotification*)aNotification {
    NSLog(@"Changed: %@",aNotification);
}

Any help appreciated


Solution

  • You don't receive a notification because you're trying to combine a notification and KVO. Some solutions:

    Solution A: connect the action of the predicate editor to an action method.

    Solution B: observe notification NSRuleEditorRowsDidChangeNotification.

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(predicateChangedByUser:) name:NSRuleEditorRowsDidChangeNotification object:self.predicateEditor];
    
    - (void)predicateChangedByUser:(NSNotification *)notification {
        NSLog(@"predicateChangedByUser");
    }
    

    Solution C: observe keypath predicate of the predicate editor. predicate is a property of NSRuleEditor.

    static void *observingContext = &observingContext;
    
    [self.predicateEditor addObserver:self forKeyPath:@"predicate" options:0 context:&observingContext];
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if (context == &observingContext)
            NSLog(@"observeValueForKeyPath %@", keyPath);
        else
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
    

    Solution D: bind the value of the editor to a predicate property.