Kex
Kex

Reputation: 8629

Detecting if a UITableViewCell is a reused cell

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

Answers (3)

Sulthan
Sulthan

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

KIDdAe
KIDdAe

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

Simon McLoughlin
Simon McLoughlin

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

Related Questions