thermogl / TITokenField

An iOS version of the NSTokenField (See To: field in Mail and Messages).
http://thermoglobalnuclearwar.com/opensource/
600 stars 172 forks source link

Bug using ContactPicker #3

Closed jpstuehler closed 12 years ago

jpstuehler commented 13 years ago

Hey Tom,

thanks for this nice piece of code. After playing around with it a bit I found an issue when using the ABPeoplePicker for the ButtonAction.

In your example project you just add a token manually when this button gets pressed. In reality when doing so the ABPeoplePicker is brought up and the tokenField resigns first responder. Now when I add a token manually the tokenField will become responder after the token was added and this leads to the deletion of all previously added tokens. So before the new token is added the tokenField should rebuilt the saved tokens and then add the new token.

You can replicate this behavior by using this code in your example project:

- (void)showContactsPicker {

    // Show some kind of contacts picker in here.
    // For now, it's a good chance to show how to add tokens.
    [tokenFieldView.tokenField resignFirstResponder];
    [tokenFieldView.tokenField addToken:@"New Name"];

    // You can access token titles with 'tokenFieldView.tokenTitles'.
    // Eg, NSLog(@"%@", tokenFieldView.tokenTitles);
}

Thanks again

thermogl commented 13 years ago

Weirdly, in using my own picker, I haven't seen this behaviour - but I don't call resignFirstResponder on the field manually.

I've changed the addToken method to make the field become first responder before adding the token. Seems to work.

jpstuehler commented 13 years ago

Sorry, for the confusion. Your last fix didn't really help with this problem.

The solution was to change the call order in the picker delegates. First the picker view needs to be dismissed and then the addToken method should be used. This way everything works fine. If you try to add a token before dismissing the picker it will screw up the results.

thermogl commented 13 years ago

I'm confused a little; You're saying it's nothing to do with the TITokenField? You just needed to change some stuff in your own code?

jpstuehler commented 13 years ago

It has something to do with TITokenfield and the issue is related to the responder chain.

I'm using the built in people picker and this way it won't work:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
      shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    [tokenFieldView.tokenField addToken:@"SomeName"];
    [self dismissModalViewControllerAnimated:YES];  
    return NO;
}

The reason for this is that the addToken method won't work correctly as long as another UI element is first responder, because all tokenNames need to be drawn before another one can be added. Changing the order in this example and first dismissing the modal view and then using addToken works just fine.

thermogl commented 13 years ago

Oh I see - well for now, obviously just swap the lines so it works.

I'll keep looking into it.