Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTokenField with mixed token/string input, possible?

When entering an invalid email in Mail's NSTokenField one get's this (a mix of token and plain string values):

alt text

Is there any recommendable way to accomplish this?
Is NSTokenField even the right tool for this? Or would I be abusing it?

In this particular project I need to allow the user to enter a file name pattern
(there are several other use cases though), with support for predefined tokens.

Right now I'm requiring the input to be entered like this:

Glue Text %[Tag]Other Glue Text%[Another Tag]More Text

I'd like to change this to some fool-proof graphical solution like this: alt text

NSTokenField always(!) turns entered text into tokens.

Either I'm using the wrong keywords in my web searches,
or I'm really the first to need this (mixed) behaviour?!

I did read thru Apple's NSTokenField Guide, but couldn't find any info on my problem.

like image 710
Regexident Avatar asked Nov 22 '10 11:11

Regexident


2 Answers

You need to implement the delegate method tokenField:styleForRepresentedObject: to return either NSRoundedTokenStyle for tokens or NSPlainTextTokenStyle for other text. The represented object for an token is the token string itself, unless your delegate returns other objects.

This should do the trick for your case:

- (NSTokenStyle)tokenField:(NSTokenField *)tokenField
 styleForRepresentedObject:(id)representedObject
{
    if ([representedObject rangeOfString: @"%["].location == 0) {
        return NSRoundedTokenStyle;
    } else {
        return NSPlainTextTokenStyle;
    }
}
like image 96
Sven Avatar answered Nov 12 '22 10:11

Sven


Actually, you first have to define a tokenizing character, which in your case would be %

[tokenField setTokenizingCharacterSet:[NSCharacterSet characterSetWithCharactersInString:@"%%"]];

The input string needs to changed as well into:

Glue Text %[Tag]%Other Glue Text%[Another Tag]%More Text

... so that Cocoa knows where the token ends.

And if you want [Tag] to be displayed as Tag in the token field, you also need to implement the tokenField:displayStringForRepresentedObject: method:

- (NSTokenStyle)tokenField:(NSTokenField *)tokenField
 displayStringForRepresentedObject:(id)representedObject
{
    if ([representedObject rangeOfString: @"["].location == 0) {
        return [(NSString*)representedObject substringWithRange:NSMakeRange(1, [(NSString*)representedObject length]-2)];

    return representedObject;
}

However, this has a big drawback : if you copy or just move a token, Cocoa will call tokenField:displayStringForRepresentedObject: and the copied/moved token will be changed to regular text Tag instead of the token [Tag].

If someone has a solution to the above problem, I'd be happy to read it.

like image 40
tijej Avatar answered Nov 12 '22 10:11

tijej