0

I have an NSTextField UI element where the user can type into the text field and I want to drop down a list of completions beneath the text field as a "live search".

I was hoping to use the native text completions infrastructure, but when the user chooses the appropriate completion, I don't want to merely put the text into the NSTextField. The user is actually choosing one of many custom objects in an NSArray by searching on string properties of the object. When they choose, I need to know which object they chose.

Is there a way to know the index of the completion that was chosen (so that I can get the object from that index in my array)?

Or do I need to forget about using the native text completions and just populate and display a dropdown under the text field?

tshepang
  • 12,111
  • 21
  • 91
  • 136
pjv
  • 566
  • 3
  • 16

2 Answers2

0

Could you use an NSComboBox in this situation? And perhaps subclass NSComboBoxCell to override

- (NSString *)completedString:(NSString *)substring

You could also observe changes in the NSComboBox delegate protocol to detect changes to the selected item

Jeff Hellman
  • 2,117
  • 18
  • 17
  • It's a good thought, but I don't want the down arrow and I am doing a few other things visually with the text field that I don't know if I could replicate with a combo box. Do you know if there is a way to suppress the display of the down arrow and make an NSComboBox look like a plain text field when the dropdown is not displaying? – pjv Jun 23 '12 at 20:11
  • I don't. Maybe you could override drawRect: – Jeff Hellman Jun 23 '12 at 20:31
  • Thanks for the idea anyway. I'm thinking to get the appearance that I really want, I will probably have to dynamically stick a single-column NSTableView on the bottom of my text field. Seems a bit of a kludge, but so far I can't think of another way to do it. Would be nice if the completion fired off a notification or told the NSTextFieldDelegate which completion was chosen when it happens. – pjv Jun 23 '12 at 21:09
0

In the end I used an NSTokenField because of some UI appearance things that NSTokenField added for me. But I think that the extra trick I came up with (below) might also work with an NSTextField. Sorry this is kind of convoluted.

In a nutshell what I did was to generate an NSMutableDictionary (an iVar) where the keys are the full completions for the partial string in the NSTokenField and the objects are the custom objects that the completion strings represent. In other words, as I am generating the custom completion strings and putting them into an NSArray to be returned from the NSTokenFieldDelegate method tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem:, I am at the same time stuffing each of those completions and the object they represent into an NSMutableDictionary with the completion as key and the object as value.

When the user "tokenizes" the completion (by hitting Return or Tab -- i modified the tokenizing characterSet so that's all that will tokenize), the NSTokenFieldDelegate method tokenField:representedObjectForEditingString: is called. Inside there, I am able to get my object from the NSMutableDictionary by using the editingString parameter as the key: [dict objectForKey:editingString]

I think it might be possible with some wrangling in the controlTextDidChange: NSTextFieldDelegate method to do the same thing with completions on an NSTextField instead of an NSTokenField using the dictionary trick, but in order to do that, I think that you would have to have the full completion in the NSTextField, grab its stringValue and then use that as the key. In my case, I did not want the whole completion in the text field, so NSTokenField's tokenizing worked better for me.

pjv
  • 566
  • 3
  • 16