piggyback
piggyback

Reputation: 9264

UITableViewCell with multiple gestures: long-press and tap

As the question states, I would like to implement two different actions for a tap and a long-press on a UITableViewCell.

I reckon I have to deselect the row at each stage and put no functions inside here:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

And then add Tap Gestures from storyboard, but Storyboard give me an error when I drag actions to prototype cells. Hints?

Upvotes: 5

Views: 16309

Answers (3)

Hemang
Hemang

Reputation: 27072

Swift:

Define Gestures like this:

fileprivate func addGestures(inCell cell: UITableViewCell, withIndexPath indexPath: IndexPath) {
    let tapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(cellTapped))
    tapGestureRecognizer.numberOfTapsRequired = 1
    tapGestureRecognizer.numberOfTouchesRequired = 1
    cell.addGestureRecognizer(tapGestureRecognizer)

    let lpgr = UILongPressGestureRecognizer.init(target: self, action: #selector(cellLongPressed))
    lpgr.minimumPressDuration = 1.0
    cell.addGestureRecognizer(lpgr)

    cell.tag = indexPath.row

    cell.selectionStyle = .none
}

@objc fileprivate func cellTapped(_ gesture: UITapGestureRecognizer) {
     //Do whatever you want to!
}

@objc fileprivate func cellLongPressed(_ gesture: UILongPressGestureRecognizer) {
    if gesture.state == .began {
         //Do whatever you want to!
    }
}

And add gesture like this:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = (tableView.dequeueReusableCell(withIdentifier: "CellIdentifier") as! UITableViewCell)

    self.addGestures(inCell: cell, withIndexPath: indexPath)
}

Upvotes: 0

anky_believeMe
anky_believeMe

Reputation: 484

try this -

In your cellForRowAtIndexPath method, you can add tap gesture and long press gesture separately and then implement them. By this your didselect function will not be required and you wont have to deSelect anything.

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellTapped:)];
    tapGestureRecognizer.numberOfTapsRequired = 1;
    tapGestureRecognizer.numberOfTouchesRequired = 1;
    cell.tag = indexPath.row;
    [cell addGestureRecognizer:tapGestureRecognizer];


UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
                         initWithTarget:self action:@selector(handleLongPress:)];
        lpgr.minimumPressDuration = 1.0; //seconds
        [cell addGestureRecognizer:lpgr];

cell.selectionStyle = UITableViewCellSelectionStyleNone;

Now,

-(void)handleLongPress:(UILongPressGestureRecognizer *)longPress
{
    // Your code here
}

-(void)cellTapped:(UITapGestureRecognizer*)tap
{
    // Your code here
}

Upvotes: 14

CoderPug
CoderPug

Reputation: 918

You can handle the single tap action with the method of UITableViewDelegate you posted above,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

for doing a UILongPressGestureRecognizer on your UITableViewCell follow this instructions.

Hope that helps.

Upvotes: 0

Related Questions