Get button click inside UITableViewCell

2019-01-01 06:07发布

I have a view controller with a table view and a separate nib for the table cell template. The cell template has some buttons. I want to access the button click along with the index of the cell clicked inside the view controller where I have defined the Table view.

So I have ViewController.h and ViewController.m where I have the UITableView and TableTemplate.h, TableTemplate.m and TableTemplate.xib where I have the nib defined. I want the button click event with cell index in ViewController.m.

Any help on how can I do that?

17条回答
听够珍惜
2楼-- · 2019-01-01 07:09

I find it simplest to subclass the button inside your cell (Swift 3):

class MyCellInfoButton: UIButton {
    var indexPath: IndexPath?
}

In your cell class:

class MyCell: UICollectionViewCell {
    @IBOutlet weak var infoButton: MyCellInfoButton!
   ...
}

In the table view's or collection view's data source, when dequeueing the cell, give the button its index path:

cell.infoButton.indexPath = indexPath

So you can just put these code into your table view controller:

@IBAction func handleTapOnCellInfoButton(_ sender: MyCellInfoButton) {
        print(sender.indexPath!) // Do whatever you want with the index path!
}

And don't forget to set the button's class in your Interface Builder and link it to the handleTapOnCellInfoButton function!


edited:

Using dependency injection. To set up calling a closure:

class MyCell: UICollectionViewCell {
    var someFunction: (() -> Void)?
    ...
    @IBAction func didTapInfoButton() {
        someFunction?()
    }
}

and inject the closure in the willDisplay method of the collection view's delegate:

 func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    (cell as? MyCell)?.someFunction = {
        print(indexPath) // Do something with the indexPath.
    }
}
查看更多
皆成旧梦
3楼-- · 2019-01-01 07:10

Instead of playing with tags, I took different approach. Made delegate for my subclass of UITableViewCell(OptionButtonsCell) and added an indexPath var. From my button in storyboard I connected @IBAction to the OptionButtonsCell and there I send delegate method with the right indexPath to anyone interested. In cell for index path I set current indexPath and it works :)

Let the code speak for itself:

Swift 3 Xcode 8

OptionButtonsTableViewCell.swift

import UIKit
protocol OptionButtonsDelegate{
    func closeFriendsTapped(at index:IndexPath)
}
class OptionButtonsTableViewCell: UITableViewCell {
    var delegate:OptionButtonsDelegate!
    @IBOutlet weak var closeFriendsBtn: UIButton!
    var indexPath:IndexPath!
    @IBAction func closeFriendsAction(_ sender: UIButton) {
        self.delegate?.closeFriendsTapped(at: indexPath)
    }
}

MyTableViewController.swift

class MyTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, OptionButtonsDelegate {...

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "optionCell") as! OptionButtonsTableViewCell
    cell.delegate = self
    cell.indexPath = indexPath
    return cell   
}

func closeFriendsTapped(at index: IndexPath) {
     print("button tapped at index:\(index)")
}
查看更多
人间绝色
4楼-- · 2019-01-01 07:13

CustomTableCell.h is a UITableViewCell:

@property (weak, nonatomic) IBOutlet UIButton *action1Button;
@property (weak, nonatomic) IBOutlet UIButton *action2Button;

MyVC.m after imports:

@interface MYTapGestureRecognizer : UITapGestureRecognizer
@property (nonatomic) NSInteger dataint;
@end

Inside "cellForRowAtIndexPath" in MyVC.m:

//CustomTableCell 
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

//Set title buttons
[cell.action1Button setTitle:[NSString stringWithString:NSLocalizedString(@"action1", nil)] forState:UIControlStateNormal];
[cell.action2Button setTitle:[NSString stringWithString:NSLocalizedString(@"action2", nil)] forState:UIControlStateNormal];

//Set visibility buttons
[cell.action1Button setHidden:FALSE];
[cell.action2Button setHidden:FALSE];

//Do 1 action
[cell.action1Button addTarget:self action:@selector(do1Action :) forControlEvents:UIControlEventTouchUpInside];

//Do 2 action
MYTapGestureRecognizer *action2Tap = [[MYTapGestureRecognizer alloc] initWithTarget:self action:@selector(do2Action :)];
cancelTap.numberOfTapsRequired = 1;
cancelTap.dataint = indexPath.row;
[cell.action2Button setUserInteractionEnabled:YES];
[cell.action2Button addGestureRecognizer:action2Tap];

MyVC.m:

-(void)do1Action :(id)sender{
//do some action that is not necessary fr data
}

-(void)do2Action :(UITapGestureRecognizer *)tapRecognizer{
MYTapGestureRecognizer *tap = (MYTapGestureRecognizer *)tapRecognizer;
numberTag = tap.dataint;
FriendRequest *fr = [_list objectAtIndex:numberTag];

//connect with a WS o do some action with fr data

//actualize list in tableView
 [self.myTableView reloadData];
}
查看更多
初与友歌
5楼-- · 2019-01-01 07:13

for swift 4:

inside the cellForItemAt ,
   
cell.chekbx.addTarget(self, action: #selector(methodname), for: .touchUpInside)

then outside of cellForItemAt
@objc func methodname()
{
//your function code
}

查看更多
美炸的是我
6楼-- · 2019-01-01 07:14

1) In your cellForRowAtIndexPath: method, assign button tag as index:

cell.yourbutton.tag = indexPath.row;

2) Add target and action for your button as below:

[cell.yourbutton addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

3) Code actions based on index as below in ViewControler:

-(void)yourButtonClicked:(UIButton*)sender
{
     if (sender.tag == 0) 
     {
         // Your code here
     }
}

Updates for multiple Section:

You can check this link to detect button click in table view for multiple row and section.

查看更多
登录 后发表回答