diff --git a/Classes/THContactPickerView.h b/Classes/THContactPickerView.h index 1eb273e..603942f 100755 --- a/Classes/THContactPickerView.h +++ b/Classes/THContactPickerView.h @@ -13,10 +13,14 @@ @protocol THContactPickerDelegate -- (void)contactPickerTextViewDidChange:(NSString *)textViewText; -- (void)contactPickerDidRemoveContact:(id)contact; -- (void)contactPickerDidResize:(THContactPickerView *)contactPickerView; -- (BOOL)contactPickerTextFieldShouldReturn:(UITextField *)textField; +@optional +- (void)contactPickerDidResize:(THContactPickerView *)contactPicker; +- (void)contactPicker:(THContactPickerView *)contactPicker didSelectContact:(id)contact; +- (void)contactPicker:(THContactPickerView *)contactPicker didRemoveContact:(id)contact; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidBeginEditing:(UITextField *)textField; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidEndEditing:(UITextField *)textField; +- (BOOL)contactPicker:(THContactPickerView *)contactPicker textFieldShouldReturn:(UITextField *)textField; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidChange:(UITextField *)textField; @end diff --git a/Classes/THContactPickerView.m b/Classes/THContactPickerView.m index c92c4c3..8b50979 100755 --- a/Classes/THContactPickerView.m +++ b/Classes/THContactPickerView.m @@ -1,6 +1,6 @@ // -// ContactPickerTextView.m -// ContactPicker +// THContactPickerView.m +// THContactPickerView // // Created by Tristan Himmelman on 11/2/12, revised by mysteriouss. // Copyright (c) 2012 Tristan Himmelman. All rights reserved. @@ -11,7 +11,7 @@ #import "THContactTextField.h" @interface THContactPickerView (){ - BOOL _shouldSelectTextView; + BOOL _shouldSelectTextField; int _lineCount; CGRect _frameOfLastView; CGFloat _contactHorizontalPadding; @@ -37,7 +37,7 @@ @implementation THContactPickerView #define kHorizontalPaddingWithBackground 2 // the amount of padding to the left and right of each contact view (when bubbles have a non white background) #define kHorizontalSidePadding 10 // the amount of padding on the left and right of the view #define kVerticalPadding 2 // amount of padding above and below each contact view -#define kTextViewMinWidth 20 // minimum width of trailing text view +#define kTextFieldMinWidth 20 // minimum width of trailing text view #define KMaxNumberOfLinesDefault 2 - (id)initWithCoder:(NSCoder *)aDecoder { @@ -83,7 +83,7 @@ - (void)setup { [self.promptLabel sizeToFit]; [self.scrollView addSubview:self.promptLabel]; - // Create TextView + // Create TextField self.textField = [[THContactTextField alloc] init]; self.textField.delegate = self; self.textField.autocorrectionType = UITextAutocorrectionTypeNo; @@ -180,7 +180,7 @@ - (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactVie THContactView *contactView = [[THContactView alloc] initWithName:name style:bubbleStyle selectedStyle:selectedStyle showComma:_showComma]; contactView.maxWidth = self.frame.size.width - self.promptLabel.frame.origin.x - 2 * _contactHorizontalPadding - 2 * kHorizontalSidePadding; - contactView.minWidth = kTextViewMinWidth + 2 * _contactHorizontalPadding; + contactView.minWidth = kTextFieldMinWidth + 2 * _contactHorizontalPadding; contactView.keyboardAppearance = self.keyboardAppearance; contactView.returnKeyType = self.returnKeyType; contactView.delegate = self; @@ -193,7 +193,7 @@ - (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactVie // if there is a selected contact, deselect it [self.selectedContactView unSelect]; self.selectedContactView = nil; - [self selectTextView]; + [self selectTextField]; } // update the position of the contacts @@ -204,13 +204,13 @@ - (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactVie [self layoutScrollView]; } completion:^(BOOL finished) { // scroll to bottom - _shouldSelectTextView = [self isFirstResponder]; + _shouldSelectTextField = [self isFirstResponder]; [self scrollToBottomWithAnimation:YES]; - // after scroll animation [self selectTextView] will be called + // after scroll animation [self selectTextField] will be called }]; } -- (void)selectTextView { +- (void)selectTextField { self.textField.hidden = NO; [self.textField becomeFirstResponder]; } @@ -311,12 +311,12 @@ - (void)removeContactView:(THContactView *)contactView { return; } - if ([self.delegate respondsToSelector:@selector(contactPickerDidRemoveContact:)]){ - [self.delegate contactPickerDidRemoveContact:[contact nonretainedObjectValue]]; + if ([self.delegate respondsToSelector:@selector(contactPicker:didRemoveContact:)]){ + [self.delegate contactPicker:self didRemoveContact:[contact nonretainedObjectValue]]; } [self removeContactByKey:contact]; - [self selectTextView]; + [self selectTextField]; if (self.selectedContactView == contactView) { self.selectedContactView = nil; @@ -407,34 +407,34 @@ - (void)layoutContactViews { } } - // Now add the textView after the contact views - CGFloat minWidth = kTextViewMinWidth + 2 * _contactHorizontalPadding; - CGFloat textViewHeight = self.lineHeight - 2 * kVerticalPadding; - CGRect textViewFrame = CGRectMake(0, 0, self.textField.frame.size.width, textViewHeight); + // Now add the textField after the contact views + CGFloat minWidth = kTextFieldMinWidth + 2 * _contactHorizontalPadding; + CGFloat textFieldHeight = self.lineHeight - 2 * kVerticalPadding; + CGRect textFieldFrame = CGRectMake(0, 0, self.textField.frame.size.width, textFieldHeight); // Check if we can add the text field on the same line as the last contact view if (self.frame.size.width - kHorizontalSidePadding - _frameOfLastView.origin.x - _frameOfLastView.size.width - minWidth >= 0){ // add to the same line - textViewFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + _contactHorizontalPadding; - textViewFrame.size.width = self.frame.size.width - textViewFrame.origin.x; + textFieldFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + _contactHorizontalPadding; + textFieldFrame.size.width = self.frame.size.width - textFieldFrame.origin.x; } else { // place text view on the next line _lineCount++; - textViewFrame.origin.x = kHorizontalSidePadding; - textViewFrame.size.width = self.frame.size.width - 2 * _contactHorizontalPadding; + textFieldFrame.origin.x = kHorizontalSidePadding; + textFieldFrame.size.width = self.frame.size.width - 2 * _contactHorizontalPadding; if (self.contacts.count == 0){ _lineCount = 0; - textViewFrame.origin.x = [self firstLineXOffset]; - textViewFrame.size.width = self.bounds.size.width - textViewFrame.origin.x; + textFieldFrame.origin.x = [self firstLineXOffset]; + textFieldFrame.size.width = self.bounds.size.width - textFieldFrame.origin.x; } } - textViewFrame.origin.y = _lineCount * self.lineHeight + kVerticalPadding + self.verticalPadding; - self.textField.frame = textViewFrame; + textFieldFrame.origin.y = _lineCount * self.lineHeight + kVerticalPadding + self.verticalPadding; + self.textField.frame = textFieldFrame; // Add text view if it hasn't been added - self.textField.center = CGPointMake(self.textField.center.x, _lineCount * self.lineHeight + textViewHeight / 2 + kVerticalPadding + self.verticalPadding); + self.textField.center = CGPointMake(self.textField.center.x, _lineCount * self.lineHeight + textFieldHeight / 2 + kVerticalPadding + self.verticalPadding); if (self.textField.superview == nil){ [self.scrollView addSubview:self.textField]; @@ -489,7 +489,7 @@ - (void)layoutScrollView { #pragma mark - THContactTextFieldDelegate -- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView { +- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textField { self.textField.hidden = NO; if (self.contacts.count) { @@ -497,19 +497,19 @@ - (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView { self.selectedContactView = [self.contacts objectForKey:[self.contactKeys lastObject]]; [self.selectedContactView select]; } else { - if ([self.delegate respondsToSelector:@selector(contactPickerTextViewDidChange:)]){ - [self.delegate contactPickerTextViewDidChange:textView.text]; + if ([self.delegate respondsToSelector:@selector(contactPicker:textFieldDidChange:)]){ + [self.delegate contactPicker:self textFieldDidChange:textField]; } } } -- (void)textFieldDidChange:(THContactTextField *)textView{ - if ([self.delegate respondsToSelector:@selector(contactPickerTextViewDidChange:)] - && !self.textField.markedTextRange) { - [self.delegate contactPickerTextViewDidChange:textView.text]; +- (void)textFieldDidChange:(THContactTextField *)textField { + if ([self.delegate respondsToSelector:@selector(contactPicker:textFieldDidChange:)] + && !self.textField.markedTextRange) { + [self.delegate contactPicker:self textFieldDidChange:textField]; } - - if ([textView.text isEqualToString:@""] && self.contacts.count == 0){ + + if ([textField.text isEqualToString:@""] && self.contacts.count == 0){ self.placeholderLabel.hidden = NO; } else { self.placeholderLabel.hidden = YES; @@ -523,12 +523,24 @@ - (void)textFieldDidChange:(THContactTextField *)textView{ } - (BOOL)textFieldShouldReturn:(UITextField *)textField { - if ([self.delegate respondsToSelector:@selector(contactPickerTextFieldShouldReturn:)]){ - return [self.delegate contactPickerTextFieldShouldReturn:textField]; + if ([self.delegate respondsToSelector:@selector(contactPicker:textFieldShouldReturn:)]){ + return [self.delegate contactPicker:self textFieldShouldReturn:textField]; } return YES; } +- (void)textFieldDidBeginEditing:(UITextField *)textField { + if ([self.delegate respondsToSelector:@selector(contactPicker:textFieldDidBeginEditing:)]){ + [self.delegate contactPicker:self textFieldDidBeginEditing:textField]; + } +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + if ([self.delegate respondsToSelector:@selector(contactPicker:textFieldDidEndEditing:)]){ + [self.delegate contactPicker:self textFieldDidEndEditing:textField]; + } +} + #pragma mark - THContactViewDelegate Functions - (void)contactViewWasSelected:(THContactView *)contactView { @@ -537,6 +549,11 @@ - (void)contactViewWasSelected:(THContactView *)contactView { } self.selectedContactView = contactView; + id contact = [self contactForContactView:contactView]; + if ([self.delegate respondsToSelector:@selector(contactPicker:didSelectContact:)]){ + [self.delegate contactPicker:self didSelectContact:[contact nonretainedObjectValue]]; + } + [self.textField resignFirstResponder]; self.textField.text = @""; self.textField.hidden = YES; @@ -547,7 +564,7 @@ - (void)contactViewWasUnSelected:(THContactView *)contactView { self.selectedContactView = nil; } - [self selectTextView]; + [self selectTextField]; // transfer the text fromt he textField within the ContactView if there was any // ***This is important if the user starts to type when a contact view is selected self.textField.text = contactView.textField.text; @@ -571,7 +588,7 @@ - (void)handleTapGesture { [self scrollToBottomWithAnimation:YES]; // Show textField - [self selectTextView]; + [self selectTextField]; // Unselect contact view [self.selectedContactView unSelect]; @@ -581,9 +598,9 @@ - (void)handleTapGesture { #pragma mark - UIScrollViewDelegate - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { - if (_shouldSelectTextView){ - _shouldSelectTextView = NO; - [self selectTextView]; + if (_shouldSelectTextField){ + _shouldSelectTextField = NO; + [self selectTextField]; } } diff --git a/Classes/THContactTextField.m b/Classes/THContactTextField.m index 88e08ca..8729e56 100755 --- a/Classes/THContactTextField.m +++ b/Classes/THContactTextField.m @@ -46,14 +46,16 @@ - (void)deleteBackward { BOOL isTextFieldEmpty = (self.text.length == 0); if (isTextFieldEmpty){ if (self.delegate && [self.delegate respondsToSelector:@selector(textFieldDidHitBackspaceWithEmptyText:)]){ - [self.delegate textFieldDidHitBackspaceWithEmptyText:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.delegate textFieldDidHitBackspaceWithEmptyText:self]; + }); } } [super deleteBackward]; } - (void)textFieldTextDidChange:(NSNotification *)notification { - if (notification.object == self) { //Since THContactView.textView is a THContactTextField + if (notification.object == self) { //Since THContactView.textField is a THContactTextField if (self.delegate && [self.delegate respondsToSelector:@selector(textFieldDidChange:)]){ [self.delegate textFieldDidChange:self]; } diff --git a/Classes/THContactView.h b/Classes/THContactView.h index 36bfba8..81ec239 100755 --- a/Classes/THContactView.h +++ b/Classes/THContactView.h @@ -21,7 +21,7 @@ @end -@interface THContactView : UIView +@interface THContactView : UIView @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) UILabel *label; diff --git a/Classes/THContactView.m b/Classes/THContactView.m index 76616a8..792a9aa 100755 --- a/Classes/THContactView.m +++ b/Classes/THContactView.m @@ -224,9 +224,9 @@ - (void)handleTapGesture { } } -#pragma mark - UITextViewDelegate +#pragma mark - UITextFieldDelegate -- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView { +- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textField { self.textField.hidden = NO; // Capture "delete" key press when cell is empty @@ -235,7 +235,7 @@ - (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView { } } -- (void)textFieldDidChange:(THContactTextField *)textField{ +- (void)textFieldDidChange:(THContactTextField *)textField { [self unSelect]; if ([self.delegate respondsToSelector:@selector(contactViewWasUnSelected:)]){ diff --git a/ContactPicker/THContactPickerViewControllerDemo.m b/ContactPicker/THContactPickerViewControllerDemo.m index 53d3958..d9daa19 100755 --- a/ContactPicker/THContactPickerViewControllerDemo.m +++ b/ContactPicker/THContactPickerViewControllerDemo.m @@ -222,11 +222,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath #pragma mark - THContactPickerTextViewDelegate -- (void)contactPickerTextViewDidChange:(NSString *)textViewText { - if ([textViewText isEqualToString:@""]){ +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidChange:(UITextField *)textField { + if ([textField.text isEqualToString:@""]){ self.filteredContacts = self.contacts; } else { - NSPredicate *predicate = [self newFilteringPredicateWithText:textViewText]; + NSPredicate *predicate = [self newFilteringPredicateWithText:textField.text]; self.filteredContacts = [self.contacts filteredArrayUsingPredicate:predicate]; } [self.tableView reloadData]; @@ -238,7 +238,7 @@ - (void)contactPickerDidResize:(THContactPickerView *)contactPickerView { self.tableView.frame = frame; } -- (void)contactPickerDidRemoveContact:(id)contact { +- (void)contactPicker:(THContactPickerView *)contactPicker didRemoveContact:(id)contact { [self.privateSelectedContacts removeObject:contact]; NSInteger index = [self.contacts indexOfObject:contact]; @@ -247,13 +247,13 @@ - (void)contactPickerDidRemoveContact:(id)contact { [self didChangeSelectedItems]; } -- (BOOL)contactPickerTextFieldShouldReturn:(UITextField *)textField { - if (textField.text.length > 0){ - NSString *contact = [[NSString alloc] initWithString:textField.text]; - [self.privateSelectedContacts addObject:contact]; - [self.contactPickerView addContact:contact withName:textField.text]; - } - return YES; +- (BOOL)contactPicker:(THContactPickerView *)contactPicker textFieldShouldReturn:(UITextField *)textField { + if (textField.text.length > 0){ + NSString *contact = [[NSString alloc] initWithString:textField.text]; + [self.privateSelectedContacts addObject:contact]; + [self.contactPickerView addContact:contact withName:textField.text]; + } + return YES; } #pragma mark - NSNotificationCenter diff --git a/README.md b/README.md index ee73306..03982a3 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,18 @@ Adding and removing contacts from the view is done with these two functions: THContactPickerView defines the following delegate protocol to make it easy for you views to respond to any changes: ```objective-c -- (void)contactPickerTextViewDidChange:(NSString *)textViewText; -- (void)contactPickerDidRemoveContact:(id)contact; -- (void)contactPickerDidResize:(THContactPickerView *)contactPickerView; -- (BOOL)contactPickerTextFieldShouldReturn:(UITextField *)textField; +@protocol THContactPickerDelegate + +@optional +- (void)contactPickerDidResize:(THContactPickerView *)contactPicker; +- (void)contactPicker:(THContactPickerView *)contactPicker didSelectContact:(id)contact; +- (void)contactPicker:(THContactPickerView *)contactPicker didRemoveContact:(id)contact; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidBeginEditing:(UITextField *)textField; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidEndEditing:(UITextField *)textField; +- (BOOL)contactPicker:(THContactPickerView *)contactPicker textFieldShouldReturn:(UITextField *)textField; +- (void)contactPicker:(THContactPickerView *)contactPicker textFieldDidChange:(UITextField *)textField; + +@end ``` ##Customization: