6

I want to know if is it a method different to

-(void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item

and

-(void)menuDidClose:(NSMenu *)menu

to help me to know when NSPopupButton's selected value changes (for example by pressing a key name instead of selecting it from the NSMenu)

Jesus
  • 8,456
  • 4
  • 28
  • 40

2 Answers2

13

first create your IBAction:

- (IBAction)mySelector:(id)sender {
    NSLog(@"My NSPopupButton selected value is: %@", [(NSPopUpButton *) sender titleOfSelectedItem]);
}

and then assign your IBAction to your NSPopupButton

    [popupbutton setAction:@selector(mySelector:)];
    [popupbutton setTarget:self];
Jesús Ayala
  • 2,743
  • 3
  • 32
  • 48
2

Combine solution (works only on iOS 13 and above)

I tried observing indexOfSelectedItem property of NSPopupButton but realised it is not KVO compatible.

Now since NSPopupButton internally uses NSMenu, I tried to find relevant notifications that NSMenu sends and found that NSMenu.didSendActionNotification can be used.

import Combine

extension NSPopUpButton {

    /// Publishes index of selected Item
    var selectionPublisher: AnyPublisher<Int, Never> {
        NotificationCenter.default
            .publisher(for: NSMenu.didSendActionNotification, object: menu)
            .map { _ in self.indexOfSelectedItem }
            .eraseToAnyPublisher()
    }
}

This extension publishes index whenever there user makes any selection in NSPopupButton.

It can be used as follows

popupButton.selectionPublisher
    .sink { (index) in
        print("Selecion \(index)")
    }
    .store(in: &storage)
Kaunteya
  • 3,107
  • 1
  • 35
  • 66