Skip to content

Commit

Permalink
Merge branch 'eliburke-protocol_fix'
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanhimmelman committed Jan 14, 2016
2 parents 60c791a + 3eb343b commit d044d21
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 67 deletions.
12 changes: 8 additions & 4 deletions Classes/THContactPickerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@

@protocol THContactPickerDelegate <NSObject>

- (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

Expand Down
101 changes: 59 additions & 42 deletions Classes/THContactPickerView.m
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -11,7 +11,7 @@
#import "THContactTextField.h"

@interface THContactPickerView ()<THContactTextFieldDelegate>{
BOOL _shouldSelectTextView;
BOOL _shouldSelectTextField;
int _lineCount;
CGRect _frameOfLastView;
CGFloat _contactHorizontalPadding;
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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];
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -489,27 +489,27 @@ - (void)layoutScrollView {

#pragma mark - THContactTextFieldDelegate

- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView {
- (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textField {
self.textField.hidden = NO;

if (self.contacts.count) {
// Capture "delete" key press when cell is empty
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;
Expand All @@ -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 {
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -571,7 +588,7 @@ - (void)handleTapGesture {
[self scrollToBottomWithAnimation:YES];

// Show textField
[self selectTextView];
[self selectTextField];

// Unselect contact view
[self.selectedContactView unSelect];
Expand All @@ -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];
}
}

Expand Down
6 changes: 4 additions & 2 deletions Classes/THContactTextField.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down
2 changes: 1 addition & 1 deletion Classes/THContactView.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

@end

@interface THContactView : UIView <UITextViewDelegate, UITextInputTraits>
@interface THContactView : UIView <UITextInputTraits>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) UILabel *label;
Expand Down
6 changes: 3 additions & 3 deletions Classes/THContactView.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -235,7 +235,7 @@ - (void)textFieldDidHitBackspaceWithEmptyText:(THContactTextField *)textView {
}
}

- (void)textFieldDidChange:(THContactTextField *)textField{
- (void)textFieldDidChange:(THContactTextField *)textField {

[self unSelect];
if ([self.delegate respondsToSelector:@selector(contactViewWasUnSelected:)]){
Expand Down
22 changes: 11 additions & 11 deletions ContactPicker/THContactPickerViewControllerDemo.m
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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];
Expand All @@ -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
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <NSObject>

@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:
Expand Down

0 comments on commit d044d21

Please sign in to comment.