Matt Sarnoff
Matt Sarnoff

Reputation: 123

Close NSTokenField completion list when an item is clicked?

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?

Upvotes: 5

Views: 646

Answers (2)

Kappe
Kappe

Reputation: 9505

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;
...
...
}

Upvotes: 0

siekfried
siekfried

Reputation: 2964

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

Upvotes: 4

Related Questions