Skip to content

Commit c4d38a8

Browse files
committed
Merge pull request jessesquires#811 from sebastianludwig/develop
Implemented jessesquires#810: An easier way to handle custom menu actions. close jessesquires#810
2 parents 9db018b + b728ff3 commit c4d38a8

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

JSQMessagesDemo/DemoMessagesViewController.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ - (void)viewDidLoad
3636
{
3737
[super viewDidLoad];
3838

39+
[JSQMessagesCollectionViewCell registerMenuAction:@selector(delete:)];
40+
3941
self.title = @"JSQMessages";
4042

4143
/**
@@ -502,7 +504,25 @@ - (UICollectionViewCell *)collectionView:(JSQMessagesCollectionView *)collection
502504
return cell;
503505
}
504506

507+
#pragma mark - UICollectionView Delegate
505508

509+
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
510+
{
511+
if (action == @selector(delete:)) {
512+
return YES;
513+
}
514+
515+
return [super collectionView:collectionView canPerformAction:action forItemAtIndexPath:indexPath withSender:sender];
516+
}
517+
518+
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
519+
{
520+
if (action == @selector(delete:)) {
521+
NSLog(@"delegate action %@", NSStringFromSelector(action));
522+
} else {
523+
[super collectionView:collectionView performAction:action forItemAtIndexPath:indexPath withSender:sender];
524+
}
525+
}
506526

507527
#pragma mark - JSQMessages collection view flow layout delegate
508528

JSQMessagesViewController/Views/JSQMessagesCollectionView.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,17 @@ - (void)messagesCollectionViewCellDidTapCell:(JSQMessagesCollectionViewCell *)ce
169169
touchLocation:position];
170170
}
171171

172+
- (void)messagesCollectionViewCell:(JSQMessagesCollectionViewCell *)cell didPerformAction:(SEL)action withSender:(id)sender
173+
{
174+
NSIndexPath *indexPath = [self indexPathForCell:cell];
175+
if (indexPath == nil) {
176+
return;
177+
}
178+
179+
[self.delegate collectionView:self
180+
performAction:action
181+
forItemAtIndexPath:indexPath
182+
withSender:sender];
183+
}
184+
172185
@end

JSQMessagesViewController/Views/JSQMessagesCollectionViewCell.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@
6060
*/
6161
- (void)messagesCollectionViewCellDidTapCell:(JSQMessagesCollectionViewCell *)cell atPosition:(CGPoint)position;
6262

63+
/**
64+
* Tells the delegate that an actions has been selected from the menu of this cell.
65+
*
66+
* @param cell The cell that displayed the menu.
67+
* @param action The action that has been performed.
68+
* @param sender The object that initiated the action.
69+
*
70+
* @discussion This method is automatically called for any registered actions.
71+
*
72+
* @see `JSQMessagesCollectionViewCell`
73+
*/
74+
- (void)messagesCollectionViewCell:(JSQMessagesCollectionViewCell *)cell didPerformAction:(SEL)action withSender:(id)sender;
75+
6376
@end
6477

6578

@@ -180,4 +193,12 @@
180193
*/
181194
+ (NSString *)mediaCellReuseIdentifier;
182195

196+
/**
197+
* Registeres an action to be available in the cell's menu.
198+
*
199+
* @discussion Non-Standard actions still need to be added to the `UIMenuController`
200+
* manually.
201+
*/
202+
+ (void)registerMenuAction:(SEL)action;
203+
183204
@end

JSQMessagesViewController/Views/JSQMessagesCollectionViewCell.m

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,21 @@ - (void)jsq_updateConstraint:(NSLayoutConstraint *)constraint withConstant:(CGFl
6666
@end
6767

6868

69+
static NSMutableArray *jsqMessagesCollectionViewCellActions = nil;
70+
6971

7072
@implementation JSQMessagesCollectionViewCell
7173

7274
#pragma mark - Class methods
7375

76+
+ (void)initialize
77+
{
78+
static dispatch_once_t onceToken;
79+
dispatch_once(&onceToken, ^{
80+
jsqMessagesCollectionViewCellActions = [[NSMutableArray alloc] init];
81+
});
82+
}
83+
7484
+ (UINib *)nib
7585
{
7686
return [UINib nibWithNibName:NSStringFromClass([self class]) bundle:[NSBundle bundleForClass:[self class]]];
@@ -86,6 +96,11 @@ + (NSString *)mediaCellReuseIdentifier
8696
return [NSString stringWithFormat:@"%@_JSQMedia", NSStringFromClass([self class])];
8797
}
8898

99+
+ (void)registerMenuAction:(SEL)action
100+
{
101+
[jsqMessagesCollectionViewCellActions addObject:NSStringFromSelector(action)];
102+
}
103+
89104
#pragma mark - Initialization
90105

91106
- (void)awakeFromNib
@@ -221,6 +236,37 @@ - (void)setBounds:(CGRect)bounds
221236
}
222237
}
223238

239+
#pragma mark - Menu actions
240+
241+
- (BOOL)respondsToSelector:(SEL)aSelector
242+
{
243+
if ([jsqMessagesCollectionViewCellActions containsObject:NSStringFromSelector(aSelector)]) {
244+
return YES;
245+
} else {
246+
return [super respondsToSelector:aSelector];
247+
}
248+
}
249+
250+
- (void)forwardInvocation:(NSInvocation *)anInvocation
251+
{
252+
if ([jsqMessagesCollectionViewCellActions containsObject:NSStringFromSelector(anInvocation.selector)]) {
253+
id sender;
254+
[anInvocation getArgument:&sender atIndex:0];
255+
[self.delegate messagesCollectionViewCell:self didPerformAction:anInvocation.selector withSender:sender];
256+
} else {
257+
[super forwardInvocation:anInvocation];
258+
}
259+
}
260+
261+
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
262+
{
263+
if ([jsqMessagesCollectionViewCellActions containsObject:NSStringFromSelector(aSelector)]) {
264+
return [NSMethodSignature signatureWithObjCTypes: "v@:@"];
265+
} else {
266+
return [super methodSignatureForSelector:aSelector];
267+
}
268+
}
269+
224270
#pragma mark - Setters
225271

226272
- (void)setBackgroundColor:(UIColor *)backgroundColor

0 commit comments

Comments
 (0)