How to programmatically open an NSComboBox's l

2019-04-28 14:52发布

问题:

I've been around this for a while.. I thought this should be an easy task, but it isn't =D

What I am trying to do, is to display the combobox's list when the user clicks the combobox but not specifically in the button.

Any Idea? Thanks in advance!

回答1:

This answer fits the title of the question, but not question itself. Omer wanted to touch a text field and have the box popup.

This solution shows the popup when the user enters text.

I found this answer on cocoabuilder from Jens Alfke. I reposted his code here. Thanks Jens.

original cocoabuilder post: (http://www.cocoabuilder.com/archive/cocoa)

@interface NSComboBox (MYExpansionAPI)
@property (getter=isExpanded) BOOL expanded;
@end

@implementation NSComboBox (MYExpansionAPI)

- (BOOL) isExpanded
{
    id ax = NSAccessibilityUnignoredDescendant(self);
    return [[ax accessibilityAttributeValue:
                NSAccessibilityExpandedAttribute] boolValue];
}

- (void) setExpanded: (BOOL)expanded
{
    id ax = NSAccessibilityUnignoredDescendant(self);
    [ax accessibilitySetValue: [NSNumber numberWithBool: expanded]
                 forAttribute: NSAccessibilityExpandedAttribute];
}

I used this code in my controlTextDidChange: method.

- (void) controlTextDidChange:(NSNotification *) aNotification {
  NSTextField *textField = [aNotification object];
  NSString *value = [textField stringValue];
  NSComboBox *box = [self comboBox];
  if (value == nil || [value length] == 0) {
    if ([box isExpanded]) { [box setExpanded:NO]; }
  } else {
    if (![box isExpanded]) { [box setExpanded:YES]; }
  }
}


回答2:

You can use the following code line:

 [(NSComboBoxCell*)self.acomboBox.cell performSelector:@selector(popUp:)];


回答3:

Thanks to jmoody and Jens Alfke mentioned above. Here is a SWIFT translation of the above solution.

import Cocoa

class CComboBoxEx: NSComboBox {

override func drawRect(dirtyRect: NSRect) {
    super.drawRect(dirtyRect)
        // Drawing code here.

       }

func isExpanded() -> Bool{

    if let ax:AnyObject? = NSAccessibilityUnignoredDescendant(self) {
        if ax!.accessibilityAttributeValue(NSAccessibilityExpandedAttribute) != nil {
            return true
        }
    }
    return false
}

func setExpanded (bExpanded:Bool) {

    if let ax:AnyObject? = NSAccessibilityUnignoredDescendant(self) {
       ax!.accessibilitySetValue(NSNumber(bool: bExpanded), forAttribute: NSAccessibilityExpandedAttribute)
    }

 }



}


回答4:

Put

comboBoxCell.performSelector(Selector("popUp:"))

Into

override func controlTextDidChange(obj: NSNotification) {}

is what I ended up with. Thanks @Ahmed Lotfy

Here's the full code, it works for me on OSX 10.11

override func controlTextDidChange(obj: NSNotification) {
        if let comboBoxCell = self.comboBox.cell as? NSComboBoxCell {
            comboBoxCell.performSelector(Selector("popUp:"))
        }
}


回答5:

  1. Returns true if the NSComboBox's list is expanded

    comboBox.cell?.isAccessibilityExpanded() ?? false
    
  2. Open the NSComboBox's list

    comboBox.cell?.setAccessibilityExpanded(true)
    
  3. Close the NSComboBox's list

    comboBox.cell?.setAccessibilityExpanded(false)
    

Ref. jmoody’s answer.



回答6:

NSComboBox was not designed to work this way. Because the user may want to edit the text in the control, they'll need to be able to click it without unexpectedly popping up the choices.

You would need to subclass NSComboBoxCell and change this behavior ... but then you'd have a standard-looking control that does not behave in a standard way. If you're determined to do this, take a look at the open source version of NSComboBoxCell. The interesting methods appear to be -popUpForComboBoxCell: and friends.