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

UIMenuController with copy action #58

Open
wants to merge 6 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ This protocol allows you to provide info about what you want to present in the t

Implement...
* ```tokenField:titleForTokenAtIndex:``` to specify what the title for the token at a particular index should be.
* ```tokenField:underlyingStringForTokenAtIndex:``` to specify what will be copied with the long press on the token at a particular index.
* ```numberOfTokensInTokenField:``` to specify how many tokens you have.
* ```tokenFieldCollapsedText:``` to specify what you want the token field to say in the collapsed state.

Expand Down
2 changes: 2 additions & 0 deletions VENTokenField/VENToken.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@

@property (assign, nonatomic) BOOL highlighted;
@property (copy, nonatomic) void (^didTapTokenBlock) (void);
@property (copy, nonatomic) void (^didLongPressTokenBlock) (void);
@property (strong, nonatomic) UIColor *colorScheme;

- (void)setTitleText:(NSString *)text;
- (void)setTokenCopyString:(NSString *)string;

@end
37 changes: 37 additions & 0 deletions VENTokenField/VENToken.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@

@interface VENToken ()
@property (strong, nonatomic) UITapGestureRecognizer *tapGestureRecognizer;
@property (strong, nonatomic) UILongPressGestureRecognizer *longPressGestureRecognizer;
@property (strong, nonatomic) IBOutlet UILabel *titleLabel;
@property (strong, nonatomic) IBOutlet UIView *backgroundView;
@property (strong, nonatomic) NSString *tokenCopyString;
@end

@implementation VENToken
Expand All @@ -43,9 +45,11 @@ - (void)setUpInit
{
self.backgroundView.layer.cornerRadius = 5;
self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapToken:)];
self.longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(didLongPressToken:)];
self.colorScheme = [UIColor blueColor];
self.titleLabel.textColor = self.colorScheme;
[self addGestureRecognizer:self.tapGestureRecognizer];
[self addGestureRecognizer:self.longPressGestureRecognizer];
}

- (void)setTitleText:(NSString *)text
Expand All @@ -57,6 +61,11 @@ - (void)setTitleText:(NSString *)text
[self.titleLabel sizeToFit];
}

- (void)setTokenCopyString:(NSString *)string
{
self.tokenCopyString = string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause an infinite loop! ♻️

}

- (void)setHighlighted:(BOOL)highlighted
{
_highlighted = highlighted;
Expand All @@ -73,6 +82,22 @@ - (void)setColorScheme:(UIColor *)colorScheme
[self setHighlighted:_highlighted];
}

#pragma mark - UIMenuController Actions

- (BOOL)canBecomeFirstResponder
{
return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return (action == @selector(copy:));
}

- (void)copy:(id)sender
{
[[UIPasteboard generalPasteboard] setString:self.tokenCopyString];
}

#pragma mark - Private

Expand All @@ -83,4 +108,16 @@ - (void)didTapToken:(UITapGestureRecognizer *)tapGestureRecognizer
}
}

- (void)didLongPressToken:(UILongPressGestureRecognizer *)longPressGestureRecognizer
{
if (self.didLongPressTokenBlock) {
self.didLongPressTokenBlock();
return;
}
[self becomeFirstResponder];
UIMenuController *menuController = [UIMenuController sharedMenuController];
[menuController setTargetRect:self.frame inView:self.superview];
[menuController setMenuVisible:YES animated:YES];
}

@end
1 change: 1 addition & 0 deletions VENTokenField/VENTokenField.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@protocol VENTokenFieldDataSource <NSObject>
@optional
- (NSString *)tokenField:(VENTokenField *)tokenField titleForTokenAtIndex:(NSUInteger)index;
- (NSString *)tokenField:(VENTokenField *)tokenField copyStringForTokenAtIndex:(NSUInteger)index;
- (NSUInteger)numberOfTokensInTokenField:(VENTokenField *)tokenField;
- (NSString *)tokenFieldCollapsedText:(VENTokenField *)tokenField;
@end
Expand Down
12 changes: 12 additions & 0 deletions VENTokenField/VENTokenField.m
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ - (void)layoutTokensWithCurrentX:(CGFloat *)currentX currentY:(CGFloat *)current
{
for (NSUInteger i = 0; i < [self numberOfTokens]; i++) {
NSString *title = [self titleForTokenAtIndex:i];
NSString *tokenCopyString = [self copyStringForTokenAtIndex:i];
VENToken *token = [[VENToken alloc] init];
token.colorScheme = self.colorScheme;

Expand All @@ -307,6 +308,7 @@ - (void)layoutTokensWithCurrentX:(CGFloat *)currentX currentY:(CGFloat *)current
};

[token setTitleText:[NSString stringWithFormat:@"%@,", title]];
[token setTokenCopyString:[NSString stringWithFormat:@"%@,", tokenCopyString]];
[self.tokens addObject:token];

if (*currentX + token.width <= self.scrollView.contentSize.width) { // token fits in current line
Expand Down Expand Up @@ -496,6 +498,16 @@ - (NSString *)titleForTokenAtIndex:(NSUInteger)index
return [NSString string];
}

- (NSString *)copyStringForTokenAtIndex:(NSUInteger)index
{
if ([self.dataSource respondsToSelector:@selector(tokenField:copyStringForTokenAtIndex:)]) {
return [self.dataSource tokenField:self copyStringForTokenAtIndex:index];
} else if ([self.dataSource respondsToSelector:@selector(tokenField:titleForTokenAtIndex:)]) {
return [self.dataSource tokenField:self titleForTokenAtIndex:index];
}
return [NSString string];
}

- (NSUInteger)numberOfTokens
{
if ([self.dataSource respondsToSelector:@selector(numberOfTokensInTokenField:)]) {
Expand Down
5 changes: 5 additions & 0 deletions VENTokenFieldSample/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ - (NSString *)tokenField:(VENTokenField *)tokenField titleForTokenAtIndex:(NSUIn
return self.names[index];
}

- (NSString *)tokenField:(VENTokenField *)tokenField copyStringForTokenAtIndex:(NSUInteger)index
{
return [NSString stringWithFormat:@"The name is: %@", self.names[index]];
}

- (NSUInteger)numberOfTokensInTokenField:(VENTokenField *)tokenField
{
return [self.names count];
Expand Down