5

I have an NSTokenField in my app. When I click one of the suggestions from the completion list, I would like the list to disappear and the token to be completed (like Mail) However, this doesn't seem to be happening--clicking a suggestion just appends the remainder of the string and the list doesn't disappear.

The completion list disappers if I press Return, but I want it to be dismissed by clicking a suggestion as well. How can I achieve this?

Matt Sarnoff
  • 113
  • 6

2 Answers2

4

I found a solution to this problem, which is not perfect yet but I hope I will soon solve the last issue I have.

I'm using rubymotion and even if I can translate Objective-C in Ruby, I'm not able to do the opposite so my answer will be in Ruby. Feel free to edit my answer to add the corresponding Objective-C code.

In the delegate of my NSTokenField, I used the controlTextDidChange method of NSControl which is called anytime I write a character in my token field. In this method I check if there is a NSLeftMouseUp event which is triggered, and if it's the case, I simulate a click on Return (learned from this other SO question). And that's it.

Here is my Ruby code:

def controlTextDidChange(aNotification)
  application = NSApplication.sharedApplication
  event = application.currentEvent
  if event.type == NSLeftMouseUp
    e1 = CGEventCreateKeyboardEvent(nil, 0x24, true)
    CGEventPost(KCGSessionEventTap, e1)
  end
end

But like I told you, it's not perfect yet: my issue is that if I have a completion list with 3 items for instance, one of them will be selected by default, let's say the first one. In this case, my solution will work as expected if I click the second or the third item but I will have to double click the first item to make it work.

But still, it's a good start and I hope it will help!

EDIT

To fix the last issue I had, I turned off the autocompletion and only displayed the suggestion box. To do so, I added this line to the tokenField:completionsForSubstring:indexOfToken:indexOfSelectedItem: method:

selectedIndex[0] = -1
Community
  • 1
  • 1
siekfried
  • 2,964
  • 1
  • 21
  • 36
  • Tried to add in the Objective-C code to your answer but my edits are being rejected... =( – rocky Sep 09 '13 at 21:03
  • if([[NSApplication sharedApplication]currentEvent].type == NSLeftMouseUp) { CGEventPost(kCGSessionEventTap, CGEventCreateKeyboardEvent(nil, 0x24, true)); } – Kappe Feb 11 '14 at 10:46
0

Thanks to @siekfried!

- (void)controlTextDidChange:(NSNotification *)aNotification;
{
    if([[NSApplication sharedApplication]currentEvent].type == NSLeftMouseUp)
    {
        CGEventPost(kCGSessionEventTap, CGEventCreateKeyboardEvent(nil, 0x24, true));
    }
}

works really well ;)

to avoid the first element automatic selection add this to your delegate:

-(NSArray *)tokenField:(NSTokenField *)tokenField completionsForSubstring:(NSString *)substring indexOfToken:(NSInteger)tokenIndex indexOfSelectedItem:(NSInteger *)selectedIndex
{
    *selectedIndex = -1;
...
...
}
Kappe
  • 9,217
  • 2
  • 29
  • 41