Reputation: 8629
In my app I have UITableView cells with multiple buttons. 4 UIButtons per cell. For each UIButton I want to add a UILongPressGestureRecognizer. Code below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FriendViewCell *cell = (FriendViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
for(int i =0; i<4; i++) {
UIButton *button = cell.buttons[i];
UILabel *label = cell.labels[i];
[button setTag:(int)indexPath.row*4+i];
[button addTarget:self action:@selector(friendTapped:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressFriend:)];
[button addGestureRecognizer:longPress];
}
}
I just realised though that if a cell is reused then I am adding a gesture multiple times per button. Is there a way to detect if the cell created is reused or new? I don't think I can move the code to the FriendViewCell class because my gesture target friendTapped: is in my UITableViewController. Any pointers will be greatly appreciated! thanks
Upvotes: 1
Views: 1134
Reputation: 130152
First of all, there are fast ways to solve this - you can check the existing gesture recognizers on the button whether there is a long press gesture recognizer.
A slightly better solution is to define a property on the cell, e.g.
@property (nonatomic, assign) BOOL recognizerAdded
However, the best solution is to do this inside the cell class
@implementation FriendViewCell
- (void)awakeFromNib {
//add the recognizers
}
@end
Note that you your table delegate shouldn't care about the structure of your cell, it's the cell's responsibility to setup itself properly.
Of course, you will need a delegate on the cell to notify you about the action but it will be a cleaner solution.
Upvotes: 1
Reputation: 2722
A cleaner way would be to create a custom class for your Button
. This class would have an UILongPressGestureRecognizer
created at initialization and a delegate (your controller) that will be called when the gesture is triggered.
.h
@class MyLongPressedButton
@protocol MyLongPressedButtonDelegate
- (void)buttonIsLongPressed:(MyLongPressedButton *)button;
@end
@interface MyLongPressedButton
@property (nonatomic, weak) id<MyLongPressedButtonDelegate > delegate
@end
.m
-(id)init {
if (self = [super init]) {
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self addGestureRecognizer:longPress];
}
return self;
}
-(void)longPress:(id)sender {
[_delegate buttonIsLongPressed:self]
}
Upvotes: 1
Reputation: 8465
I would recommend placing the code inside your cell and creating a delegate method that will return a reference to the cell.
E.g.
@protocol myAwesomebuttonCellDelegate <NSObject>
- (void)myAwesomeCell:(MyAwesomeCell *)cell buttonPressed:(UIButton *)btn;
@end
Then in your view controller you can use:
NSIndexPath *index = [tblView indexPathForCell:cell];
to get the row / section
Upvotes: 0