. :
#import "CopyableCell.h"
#import "NamedAction.h"
static const CFTimeInterval kLongPressMinimumDurationSeconds = 0.5;
@interface CopyableCell(Private)
- (void) initialize;
- (void) menuWillHide:(NSNotification *)notification;
- (void) menuWillShow:(NSNotification *)notification;
- (void) handleLongPress:(UILongPressGestureRecognizer *)longPressRecognizer;
@end
@implementation CopyableCell
@synthesize data, indexPath, delegate, customMenus;
- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
return self;
[self initialize];
return self;
}
- (void) initialize
{
self.data = nil;
self.indexPath = nil;
self.delegate = nil;
self.customMenus = nil;
self.selectionStyle = UITableViewCellSelectionStyleNone;
UILongPressGestureRecognizer *recognizer =
[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[recognizer setMinimumPressDuration:kLongPressMinimumDurationSeconds];
[self addGestureRecognizer:recognizer];
[recognizer release];
}
- (void) setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
- (void) dealloc
{
[self.customMenus release];
[self.data release];
[self.indexPath release];
[super dealloc];
}
#pragma mark -
#pragma mark Copy Menu related methods
- (BOOL) isCustomActionExists:(SEL)sel
{
if (self.customMenus != nil) {
for (int i = 0; i < customMenus.count; i++) {
NamedAction *namedItem = [customMenus objectAtIndex:i];
if (sel == namedItem.action)
return YES;
}
}
return NO;
}
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
if (self.customMenus != nil) {
if ([self isCustomActionExists:action])
return YES;
} else {
if (action == @selector(copy:))
return YES;
}
return [super canPerformAction:action withSender:sender];
}
- (void) copyToPastboard:(NSString *)dataText
{
[[UIPasteboard generalPasteboard] setString:dataText];
[self resignFirstResponder];
}
- (void) copy:(id)sender
{
if ((self.delegate != nil) &&
[self.delegate respondsToSelector:@selector(copyableCell:dataForCellAtIndexPath:)]) {
NSString *dataText = [self.delegate copyableCell:self dataForCellAtIndexPath:self.indexPath];
[self copyToPastboard:dataText];
} else if (self.data != nil) {
[self copyToPastboard:self.data];
}
}
- (BOOL) canBecomeFirstResponder
{
return YES;
}
- (BOOL) becomeFirstResponder
{
return [super becomeFirstResponder];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
if ([self isFirstResponder] == NO)
return;
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuVisible:NO animated:YES];
[menu update];
[self resignFirstResponder];
}
- (void) menuWillHide:(NSNotification *)notification
{
if ((self.delegate != nil) && [self.delegate respondsToSelector:@selector(copyableCell:deselectCellAtIndexPath:)])
[self.delegate copyableCell:self deselectCellAtIndexPath:self.indexPath];
self.selectionStyle = oldStyle;
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillHideMenuNotification object:nil];
}
- (void) menuWillShow:(NSNotification *)notification
{
oldStyle = self.selectionStyle;
self.selectionStyle = UITableViewCellSelectionStyleBlue;
if ((self.delegate != nil) && [self.delegate respondsToSelector:@selector(copyableCell:selectCellAtIndexPath:)])
[self.delegate copyableCell:self selectCellAtIndexPath:self.indexPath];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(menuWillHide:)
name:UIMenuControllerWillHideMenuNotification
object:nil];
}
#pragma mark -
#pragma mark UILongPressGestureRecognizer Handler Methods
#include <objc/runtime.h>
void dynamicMethodIMP(id self, SEL sel) {
if ([self isCustomActionExists:sel])
[((CopyableCell *)self).delegate performSelector:sel withObject:self withObject:nil];
}
+ (BOOL) resolveInstanceMethod:(SEL)sel {
class_addMethod([self class], sel, (IMP)dynamicMethodIMP, "v@:");
return YES;
}
- (void) handleLongPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
if (longPressRecognizer.state != UIGestureRecognizerStateBegan)
return;
if ([self becomeFirstResponder] == NO)
return;
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setTargetRect:self.bounds inView:self];
NSMutableArray *menuItems = nil;
if (self.customMenus != nil && customMenus.count > 0) {
menuItems = [[[NSMutableArray alloc] init] autorelease];
for (int i = 0; i < customMenus.count; i++) {
NamedAction *namedItem = [customMenus objectAtIndex:i];
UIMenuItem *emailItem = [[UIMenuItem alloc] initWithTitle:namedItem.name
action:namedItem.action];
[menuItems addObject:[emailItem autorelease]];
}
}
menu.menuItems = menuItems;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(menuWillShow:)
name:UIMenuControllerWillShowMenuNotification
object:nil];
[menu setMenuVisible:YES animated:YES];
}
@end
*.h :
#import <UIKit/UIKit.h>
@protocol CopyableCellDelegate;
@interface CopyableCell: UITableViewCell
{
NSString *data;
NSArray *customMenus;
NSIndexPath *indexPath;
UITableViewCellSelectionStyle oldStyle;
}
@property (nonatomic, retain) NSString *data;
@property (nonatomic, retain) NSArray *customMenus;
@property (nonatomic, retain) NSIndexPath *indexPath;
@property (nonatomic, assign) id<CopyableCellDelegate> delegate;
- (void) copyToPastboard:(NSString *)dataText;
@end
@protocol CopyableCellDelegate<NSObject>
@required
- (void) copyableCell:(CopyableCell *)cell selectCellAtIndexPath:(NSIndexPath *)indexPath;
- (void) copyableCell:(CopyableCell *)cell deselectCellAtIndexPath:(NSIndexPath *)indexPath;
@optional
- (NSString *) copyableCell:(CopyableCell *)cell dataForCellAtIndexPath:(NSIndexPath *)indexPath;
@end
-:
#import <Foundation/Foundation.h>
@interface NamedAction : NSObject {
NSString *name;
SEL action;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) SEL action;
- (id)initWithName:(NSString *)_name action:(SEL)_action;
@end
Implementation:
#import "NamedAction.h"
@implementation NamedAction
@synthesize name, action;
- (id)initWithName:(NSString *)_name action:(SEL)_action
{
if (self = [super init]) {
self.name = _name;
self.action = _action;
}
return self;
}
- (void)dealloc {
self.name = NULL;
self.action = NULL;
[super dealloc];
}
@end
source
share