Skip to content

Commit

Permalink
Merge pull request #46 from tristanhimmelman/custom-bubblestyle
Browse files Browse the repository at this point in the history
Custom bubblestyle
  • Loading branch information
tristanhimmelman committed Aug 31, 2015
2 parents 1894b47 + e0d5127 commit 6b02205
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 40 deletions.
1 change: 1 addition & 0 deletions Classes/THContactPickerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
@property (nonatomic, strong) UIFont *font;

- (void)addContact:(id)contact withName:(NSString *)name;
- (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactViewStyle*)bubbleStyle andSelectedStyle:(THContactViewStyle*) selectedStyle;
- (void)removeContact:(id)contact;
- (void)removeAllContacts;
- (BOOL)resignFirstResponder;
Expand Down
77 changes: 46 additions & 31 deletions Classes/THContactPickerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ @interface THContactPickerView ()<THContactTextFieldDelegate>{
BOOL _shouldSelectTextView;
int _lineCount;
CGRect _frameOfLastView;
CGFloat _contactHorizontalPadding;
BOOL _showComma;
}

@property (nonatomic, strong) UIScrollView *scrollView;
Expand All @@ -30,12 +32,13 @@ @interface THContactPickerView ()<THContactTextFieldDelegate>{

@implementation THContactPickerView

#define kVerticalViewPadding 5 // the amount of padding on top and bottom of the view
#define kHorizontalPadding 0 // the amount of padding to the left and right of each contact view
#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 KMaxNumberOfLinesDefault 2
#define kVerticalViewPadding 5 // the amount of padding on top and bottom of the view
#define kHorizontalPadding 0 // the amount of padding to the left and right of each contact view
#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 KMaxNumberOfLinesDefault 2

- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
Expand Down Expand Up @@ -146,6 +149,10 @@ - (void)setBackgroundColor:(UIColor *)backgroundColor{
}

- (void)addContact:(id)contact withName:(NSString *)name {
[self addContact:contact withName:name withStyle:self.contactViewStyle andSelectedStyle:self.contactViewSelectedStyle];
}

- (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactViewStyle *)bubbleStyle andSelectedStyle:(THContactViewStyle *)selectedStyle {
id contactKey = [NSValue valueWithNonretainedObject:contact];
if ([self.contactKeys containsObject:contactKey]){
NSLog(@"Cannot add the same object twice to ContactPickerView");
Expand All @@ -158,37 +165,45 @@ - (void)addContact:(id)contact withName:(NSString *)name {
}

self.textField.text = @"";

THContactView *contactView = [[THContactView alloc] initWithName:name style:self.contactViewStyle selectedStyle:self.contactViewSelectedStyle showComma:!self.limitToOne];
contactView.maxWidth = self.frame.size.width - self.promptLabel.frame.origin.x - 2 * kHorizontalPadding - 2 * kHorizontalSidePadding;
contactView.minWidth = kTextViewMinWidth + 2 * kHorizontalPadding;

if ([bubbleStyle hasNonWhiteBackground]){
_contactHorizontalPadding = kHorizontalPaddingWithBackground;
_showComma = NO;
} else {
_contactHorizontalPadding = kHorizontalPadding;
_showComma = !self.limitToOne;
}

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.keyboardAppearance = self.keyboardAppearance;
contactView.returnKeyType = self.returnKeyType;
contactView.delegate = self;
[contactView setFont:self.font];
[contactView setFont:self.font];
[self.contacts setObject:contactView forKey:contactKey];
[self.contactKeys addObject:contactKey];
if (self.selectedContactView){
// if there is a selected contact, deselect it
// if there is a selected contact, deselect it
[self.selectedContactView unSelect];
self.selectedContactView = nil;
[self selectTextView];
}

// update the position of the contacts
[self layoutContactViews];
// update the position of the contacts
[self layoutContactViews];
// update size of the scrollView
[UIView animateWithDuration:0.2 animations:^{
[self layoutScrollView];
} completion:^(BOOL finished) {
// scroll to bottom
_shouldSelectTextView = [self isFirstResponder];
[self scrollToBottomWithAnimation:YES];
// after scroll animation [self selectTextView] will be called
}];
[UIView animateWithDuration:0.2 animations:^{
[self layoutScrollView];
} completion:^(BOOL finished) {
// scroll to bottom
_shouldSelectTextView = [self isFirstResponder];
[self scrollToBottomWithAnimation:YES];
// after scroll animation [self selectTextView] will be called
}];
}

- (void)selectTextView {
Expand Down Expand Up @@ -366,11 +381,11 @@ - (void)layoutContactViews {
contactViewFrame.origin.y = kVerticalPadding + self.verticalPadding;
} else {
// Check if contact view will fit on the current line
CGFloat width = contactViewFrame.size.width + 2 * kHorizontalPadding;
CGFloat width = contactViewFrame.size.width + 2 * _contactHorizontalPadding;
if (self.frame.size.width - kHorizontalSidePadding - _frameOfLastView.origin.x - _frameOfLastView.size.width - width >= 0){
// add to the same line
// Place contact view just after last contact view on the same line
contactViewFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + kHorizontalPadding * 2;
contactViewFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + _contactHorizontalPadding * 2;
contactViewFrame.origin.y = _frameOfLastView.origin.y;
} else {
// No space on current line, jump to next line
Expand All @@ -389,20 +404,20 @@ - (void)layoutContactViews {
}

// Now add the textView after the contact views
CGFloat minWidth = kTextViewMinWidth + 2 * kHorizontalPadding;
CGFloat minWidth = kTextViewMinWidth + 2 * _contactHorizontalPadding;
CGFloat textViewHeight = self.lineHeight - 2 * kVerticalPadding;
CGRect textViewFrame = CGRectMake(0, 0, self.textField.frame.size.width, textViewHeight);

// 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 + kHorizontalPadding;
textViewFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + _contactHorizontalPadding;
textViewFrame.size.width = self.frame.size.width - textViewFrame.origin.x;
} else {
// place text view on the next line
_lineCount++;

textViewFrame.origin.x = kHorizontalSidePadding;
textViewFrame.size.width = self.frame.size.width - 2 * kHorizontalPadding;
textViewFrame.size.width = self.frame.size.width - 2 * _contactHorizontalPadding;

if (self.contacts.count == 0){
_lineCount = 0;
Expand Down
24 changes: 16 additions & 8 deletions Classes/THContactView.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
#import "THContactView.h"
#import "THContactTextField.h"

@interface THContactView ()<THContactTextFieldDelegate>
@interface THContactView ()<THContactTextFieldDelegate>{
CGFloat _horizontalPadding;
}

@end

@implementation THContactView

#define kHorizontalPadding 3
#define kHorizontalPaddingWithBackground 8
#define kVerticalPadding 2

#define kDefaultBorderWidth 1
Expand Down Expand Up @@ -79,6 +82,13 @@ - (id)initWithName:(NSString *)name style:(THContactViewStyle *)style selectedSt

self.style = style;
self.selectedStyle = selectedStyle;

if ([style hasNonWhiteBackground]){
_horizontalPadding = kHorizontalPaddingWithBackground;
} else {
_horizontalPadding = kHorizontalPadding;
}

[self setupView];
}
return self;
Expand Down Expand Up @@ -107,7 +117,7 @@ - (void)setupView {
tapGesture.numberOfTouchesRequired = 1;
[self addGestureRecognizer:tapGesture];

self.maxWidth = 2 * kHorizontalPadding;
self.maxWidth = 2 * _horizontalPadding;
self.minWidth = 2 * kVerticalPadding;

[self adjustSize];
Expand All @@ -119,11 +129,11 @@ - (void)adjustSize {
// Adjust the label frames
[self.label sizeToFit];
CGRect frame = self.label.frame;
frame.origin.x = kHorizontalPadding;
frame.origin.x = _horizontalPadding;
frame.origin.y = kVerticalPadding;

CGFloat maxWidth = self.maxWidth - 2 * kHorizontalPadding;
CGFloat minWidth = self.minWidth - 2 * kHorizontalPadding;
CGFloat maxWidth = self.maxWidth - 2 * _horizontalPadding;
CGFloat minWidth = self.minWidth - 2 * _horizontalPadding;

if (minWidth < maxWidth) {
if (frame.size.width < minWidth) {
Expand All @@ -139,7 +149,7 @@ - (void)adjustSize {


// Adjust view frame
self.bounds = CGRectMake(0, 0, frame.size.width + 2 * kHorizontalPadding, frame.size.height + 2 * kVerticalPadding);
self.bounds = CGRectMake(0, 0, frame.size.width + 2 * _horizontalPadding, frame.size.height + 2 * kVerticalPadding);

// Create gradient layer
if (self.gradientLayer == nil){
Expand Down Expand Up @@ -216,8 +226,6 @@ - (void)handleTapGesture {

#pragma mark - UITextViewDelegate



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

Expand Down
7 changes: 7 additions & 0 deletions Classes/THContactViewStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@
borderColor:(UIColor *)borderColor
borderWidth:(CGFloat)borderWidth
cornerRadiusFactor:(CGFloat)cornerRadiusFactor;

- (id)initWithTextColor:(UIColor *)textColor
backgroundColor:(UIColor *)backgroundColor
cornerRadiusFactor:(CGFloat)cornerRadiusFactor;

- (BOOL)hasNonWhiteBackground;

@end
15 changes: 15 additions & 0 deletions Classes/THContactViewStyle.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@

@implementation THContactViewStyle

- (id)initWithTextColor:(UIColor *)textColor
backgroundColor:(UIColor *)backgroundColor
cornerRadiusFactor:(CGFloat)cornerRadiusFactor {

return [self initWithTextColor:textColor gradientTop:backgroundColor gradientBottom:backgroundColor borderColor:backgroundColor borderWidth:0 cornerRadiusFactor:cornerRadiusFactor];
}

- (id)initWithTextColor:(UIColor *)textColor
gradientTop:(UIColor *)gradientTop
gradientBottom:(UIColor *)gradientBottom
Expand All @@ -25,7 +32,15 @@ - (id)initWithTextColor:(UIColor *)textColor
self.borderWidth = borderWidth;
self.cornerRadiusFactor = cornerRadiusFactor;
}

return self;
}

- (BOOL)hasNonWhiteBackground {
if (self.gradientTop == nil || self.gradientTop == [UIColor whiteColor] || self.gradientTop == [UIColor clearColor]){
return NO;
}
return YES;
}

@end
12 changes: 11 additions & 1 deletion ContactPicker/THContactPickerViewControllerDemo.m
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,18 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.privateSelectedContacts addObject:contact];
[self.contactPickerView addContact:contact withName:contactTilte];
//
// UIColor *color = [UIColor blueColor];
// if (self.privateSelectedContacts.count % 2 == 0){
// color = [UIColor orangeColor];
// } else if (self.privateSelectedContacts.count % 3 == 0){
// color = [UIColor purpleColor];
// }
// THContactViewStyle *style = [[THContactViewStyle alloc] initWithTextColor:[UIColor whiteColor] backgroundColor:color cornerRadiusFactor:2.0];
// THContactViewStyle *selectedStyle = [[THContactViewStyle alloc] initWithTextColor:[UIColor whiteColor] backgroundColor:[UIColor greenColor] cornerRadiusFactor:2.0];
// [self.contactPickerView addContact:contact withName:contactTilte withStyle:style andSelectedStyle:selectedStyle];
}
self.filteredContacts = self.contacts;
[self didChangeSelectedItems];
[self.tableView reloadData];
Expand Down
Binary file added screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6b02205

Please sign in to comment.