Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make scroll horizontal #59

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Classes/THContactPickerView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#import <UIKit/UIKit.h>
#import "THContactView.h"

#import "THContactTextField.h"
@class THContactPickerView;

@protocol THContactPickerDelegate <NSObject>
Expand All @@ -26,6 +26,7 @@

@interface THContactPickerView : UIView <UITextViewDelegate, THContactViewDelegate, UIScrollViewDelegate, UITextInputTraits>

@property (nonatomic, strong) THContactTextField *textField;
@property (nonatomic, strong) THContactView *selectedContactView;
@property (nonatomic, assign) IBOutlet id <THContactPickerDelegate>delegate;

Expand All @@ -34,6 +35,8 @@
@property (nonatomic, assign) NSInteger maxNumberOfLines; // maximum number of lines the view will display before scrolling
@property (nonatomic, strong) UIFont *font;

@property (nonatomic, assign) BOOL scrollHorizontal; // scroll to horizontal

- (void)addContact:(id)contact withName:(NSString *)name;
- (void)addContact:(id)contact withName:(NSString *)name withStyle:(THContactViewStyle*)bubbleStyle andSelectedStyle:(THContactViewStyle*) selectedStyle;
- (void)removeContact:(id)contact;
Expand All @@ -44,6 +47,7 @@
- (void)setContactViewStyle:(THContactViewStyle *)color selectedStyle:(THContactViewStyle *)selectedColor;
- (void)setPlaceholderLabelText:(NSString *)text;
- (void)setPlaceholderLabelTextColor:(UIColor *)color;
- (void)setPlaceholderLabelAttributedText:(NSAttributedString *)attributedText;
- (void)setPromptLabelText:(NSString *)text;
- (void)setPromptLabelAttributedText:(NSAttributedString *)attributedText;
- (void)setPromptLabelTextColor:(UIColor *)color;
Expand Down
83 changes: 68 additions & 15 deletions Classes/THContactPickerView.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ @interface THContactPickerView ()<THContactTextFieldDelegate>{
@property (nonatomic, strong) UILabel *placeholderLabel;
@property (nonatomic, strong) UILabel *promptLabel;
@property (nonatomic, assign) CGFloat lineHeight;
@property (nonatomic, strong) THContactTextField *textField;
@property (nonatomic, strong) THContactViewStyle *contactViewStyle;
@property (nonatomic, strong) THContactViewStyle *contactViewSelectedStyle;

Expand All @@ -37,7 +36,8 @@ @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 kTextFieldMinWidth 20 // minimum width of trailing text view
#define kContactViewMinWidth 20 // minimum width of trailing text view
#define kTextFieldMinWidth 80 // minimum width of trailing text view
#define KMaxNumberOfLinesDefault 2

- (id)initWithCoder:(NSCoder *)aDecoder {
Expand Down Expand Up @@ -90,7 +90,7 @@ - (void)setup {

self.backgroundColor = [UIColor whiteColor];

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture)];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
[self addGestureRecognizer:tapGesture];
Expand Down Expand Up @@ -139,6 +139,11 @@ - (void)setPlaceholderLabelTextColor:(UIColor *)color{
self.placeholderLabel.textColor = color;
}

- (void)setPlaceholderLabelAttributedText:(NSAttributedString *)attributedText
{
self.placeholderLabel.attributedText = attributedText;
}

- (void)setPromptLabelTextColor:(UIColor *)color{
self.promptLabel.textColor = color;
}
Expand Down Expand Up @@ -180,7 +185,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 = kTextFieldMinWidth + 2 * _contactHorizontalPadding;
contactView.minWidth = kContactViewMinWidth + 2 * _contactHorizontalPadding;
contactView.keyboardAppearance = self.keyboardAppearance;
contactView.returnKeyType = self.returnKeyType;
contactView.delegate = self;
Expand Down Expand Up @@ -304,6 +309,23 @@ - (void)scrollToBottomWithAnimation:(BOOL)animated {
}
}


//- (void)scrollToRightWithAnimation:(BOOL)animated {
// if (animated){
// CGSize size = self.scrollView.contentSize;
// CGRect frame = CGRectMake(size.width - self.scrollView.frame.size.width, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
//
// [self.scrollView scrollRectToVisible:frame animated:animated];
// } else {
// // this block is here because scrollRectToVisible with animated NO causes crashes on iOS 5 when the user tries to delete many contacts really quickly
// CGPoint offset = self.scrollView.contentOffset;
//
// offset.x = self.scrollView.contentSize.width - self.scrollView.frame.size.width;
//
// self.scrollView.contentOffset = offset;
// }
//}

- (void)removeContactView:(THContactView *)contactView {
id contact = [self contactForContactView:contactView];

Expand Down Expand Up @@ -386,7 +408,7 @@ - (void)layoutContactViews {
} else {
// Check if contact view will fit on the current line
CGFloat width = contactViewFrame.size.width + 2 * _contactHorizontalPadding;
if (self.frame.size.width - kHorizontalSidePadding - _frameOfLastView.origin.x - _frameOfLastView.size.width - width >= 0){
if (self.frame.size.width - kHorizontalSidePadding - _frameOfLastView.origin.x - _frameOfLastView.size.width - width >= 0 || self.scrollHorizontal){
// 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 + _contactHorizontalPadding * 2;
Expand All @@ -413,9 +435,15 @@ - (void)layoutContactViews {
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
textFieldFrame.origin.x = _frameOfLastView.origin.x + _frameOfLastView.size.width + _contactHorizontalPadding;
textFieldFrame.size.width = self.frame.size.width - textFieldFrame.origin.x;
if (self.frame.size.width - kHorizontalSidePadding - _frameOfLastView.origin.x - _frameOfLastView.size.width - minWidth >= 0 || self.scrollHorizontal){ // add to the same line
if (self.contacts.count == 0 && self.scrollHorizontal){
_lineCount = 0;
textFieldFrame.origin.x = [self firstLineXOffset];
}
else{
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++;
Expand All @@ -429,7 +457,7 @@ - (void)layoutContactViews {
textFieldFrame.size.width = self.bounds.size.width - textFieldFrame.origin.x;
}
}
textFieldFrame.size.width = fmax(minWidth,textFieldFrame.size.width);
textFieldFrame.origin.y = _lineCount * self.lineHeight + kVerticalPadding + self.verticalPadding;
self.textField.frame = textFieldFrame;

Expand Down Expand Up @@ -465,6 +493,18 @@ - (void)layoutSubviews {
- (void)layoutScrollView {
// Adjust scroll view content size
CGRect frame = self.bounds;
if (_scrollHorizontal) {
self.scrollView.contentSize = CGSizeMake(self.textField.frame.origin.x + self.textField.frame.size.width, self.lineHeight + 2 * self.verticalPadding);
frame.size.height = self.scrollView.contentSize.height;
self.scrollView.frame = frame;
CGRect selfFrame = self.frame;
selfFrame.size.height = frame.size.height;
self.frame = selfFrame;
if ([self.delegate respondsToSelector:@selector(contactPickerDidResize:)]){
[self.delegate contactPickerDidResize:self];
}
return;
}
CGFloat maxFrameHeight = self.maxNumberOfLines * self.lineHeight + 2 * self.verticalPadding; // limit frame to two lines of content
CGFloat newHeight = (_lineCount + 1) * self.lineHeight + 2 * self.verticalPadding;
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width, newHeight);
Expand Down Expand Up @@ -516,9 +556,17 @@ - (void)textFieldDidChange:(THContactTextField *)textField {
}

CGPoint offset = self.scrollView.contentOffset;
offset.y = self.scrollView.contentSize.height - self.scrollView.frame.size.height;
if (offset.y > self.scrollView.contentOffset.y){
[self scrollToBottomWithAnimation:YES];
if (self.scrollHorizontal) {
offset.x = self.scrollView.contentSize.width - self.scrollView.frame.size.width;
if (offset.x > self.scrollView.contentOffset.x){
[self scrollToBottomWithAnimation:YES];
}
}
else{
offset.y = self.scrollView.contentSize.height - self.scrollView.frame.size.height;
if (offset.y > self.scrollView.contentOffset.y){
[self scrollToBottomWithAnimation:YES];
}
}
}

Expand Down Expand Up @@ -563,8 +611,8 @@ - (void)contactViewWasUnSelected:(THContactView *)contactView {
if (self.selectedContactView == contactView){
self.selectedContactView = nil;
}

[self selectTextField];
self.textField.hidden = NO;
//[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 @@ -581,10 +629,15 @@ - (void)contactViewShouldBeRemoved:(THContactView *)contactView {

#pragma mark - Gesture Recognizer

- (void)handleTapGesture {
- (void)handleTapGesture:(UITapGestureRecognizer*)gesture {
if (self.limitToOne && self.contactKeys.count == 1){
return;
}
CGPoint tapPoint = [gesture locationInView:self.scrollView];
if (!CGRectContainsPoint(self.textField.frame, tapPoint)) {
// Do stuff if they tapped anywhere outside the text field
return;
}
[self scrollToBottomWithAnimation:YES];

// Show textField
Expand Down
2 changes: 2 additions & 0 deletions ContactPicker/THContactPickerViewControllerDemo.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ - (void)viewDidLoad {
self.contactPickerView.delegate = self;
[self.contactPickerView setPlaceholderLabelText:@"Who would you like to message?"];
[self.contactPickerView setPromptLabelText:@"To:"];
[self.contactPickerView setMaxNumberOfLines:1];
self.contactPickerView.scrollHorizontal = YES;
//[self.contactPickerView setLimitToOne:YES];
[self.view addSubview:self.contactPickerView];

Expand Down