在UI表格视图单元格内获取button

我有一个ViewController的tableview和单元格的表格单元格模板。 单元格模板有一些button。 我想访问button点击以及在已经定义了Table视图的View控制器内单击的单元格的索引。

所以我有ViewController.hViewController.m我有UItableviewTableTemplate.hTableTemplate.mTableTemplate.xib我有定义的笔尖。 我想要在ViewController.m使用单元ViewController.m引的button单击事件

任何帮助我怎么能做到这一点?

1)在cellForRowAtIndexPath:方法中,将button标签指定为索引:

 cell.yourbutton.tag = indexPath.row; 

2)为你的button添加目标和动作如下:

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

3)在ViewControler基于索引的代码动作如下:

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

更新多个部分:

你可以检查这个链接来检测button在表格视图中点击多行和部分。

代表们是要走的路。

正如其他答案使用视图可能会过时。 谁知道明天可能会有另一个包装,可能需要使用cell superview]superview]superview]superview]查看cell superview]superview]superview]superview] 。 如果你使用标签,你最终会得到n个if条件来标识单元格。 为了避免所有的设立代表。 (通过这样做,您将创build一个可用的单元类。您可以使用与基类相同的单元类,并且只需实现委托方法即可)。

首先,我们需要一个接口(协议),这个接口将被单元用来沟通(委托)button点击。 ( 您可以为协议创build一个单独的.h文件,并包含在表视图控制器和自定义单元类中,或者只是将其添加到自定义单元类中,无论如何,它将包含在表视图控制器中

 @protocol CellDelegate <NSObject> - (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data; @end 

在自定义单元格和表格视图控制器中包含此协议。 并确保表视图控制器确认此协议。

在定制单元格中创build两个属性:

 @property (weak, nonatomic) id<CellDelegate>delegate; @property (assign, nonatomic) NSInteger cellIndex; 

UIButton IBAction委托中,单击:( 对于需要委托给视图控制器的自定义单元类中的任何操作,也可以执行此操作

 - (IBAction)buttonClicked:(UIButton *)sender { if (self.delegate && [self.delegate respondsToSelector:@selector(didClickOnCellAtIndex:withData:)]) { [self.delegate didClickOnCellAtIndex:_cellIndex withData:@"any other cell data/property"]; } } 

在表单视图控制器cellForRowAtIndexPath取出单元格后,设置上述属性。

 cell.delegate = self; cell.cellIndex = indexPath.row; // Set indexpath if its a grouped table. 

并在表视图控制器中实现委托:

 - (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data { // Do additional actions as required. NSLog(@"Cell at Index: %d clicked.\n Data received : %@", cellIndex, data); } 

这将是在表视图控制器中获取自定义单元格button操作的理想方法。

这应该有助于:

 UITableViewCell* cell = (UITableViewCell*)[sender superview]; NSIndexPath* indexPath = [myTableView indexPathForCell:cell]; 

这里sender是发送事件的UIButton实例。 myTableView是你正在处理的UITableView实例。

只要获得单元格引用,所有的工作就完成了。

您可能需要从单元格的contentView中删除button,并将它们直接添加到UITableViewCell实例,因为它是子视图。

要么

你可以在cell.contentView中为不同的UIButtons制定一个标签命名scheme。 使用这个标签,以后你可以根据需要知道行和部分的信息。

我不是玩标签,而是采取了不同的方法。 为我的UITableViewCell(OptionButtonsCell)的子类做了委托,并添加了一个indexPath var。 从我的故事板button中,我将@IBAction连接到了OptionButtonsCell,在那里我发送了正确的indexPath的委托方法给任何感兴趣的人。 在索引path的单元格中,我设置了当前的索引path,它工作:)

让代码自己说话:

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)") } 

以下代码可能会帮助你。

我已经把UITableViewUIViewController名为UITableViewCell自定义原型单元类。

所以我有ViewController.hViewController.mTableViewCell.hTableViewCell.m

这是这个代码:

ViewController.h

 @interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> @property (strong, nonatomic) IBOutlet UITableView *tblView; @end 

ViewController.m

 @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return (YourNumberOfRows); } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *cellIdentifier = @"cell"; __weak TableViewCell *cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; if (indexPath.row==0) { [cell setDidTapButtonBlock:^(id sender) { // Your code here }]; } return cell; } 

自定义单元格类:

 TableViewCell.h @interface TableViewCell : UITableViewCell @property (copy, nonatomic) void (^didTapButtonBlock)(id sender); @property (strong, nonatomic) IBOutlet UILabel *lblTitle; @property (strong, nonatomic) IBOutlet UIButton *btnAction; - (void)setDidTapButtonBlock:(void (^)(id sender))didTapButtonBlock; @end 

 UITableViewCell.m @implementation TableViewCell - (void)awakeFromNib { // Initialization code [self.btnAction addTarget:self action:@selector(didTapButton:) forControlEvents:UIControlEventTouchUpInside]; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } - (void)didTapButton:(id)sender { if (self.didTapButtonBlock) { self.didTapButtonBlock(sender); } } 

注意 :在这里我已经采用了所有使用Storyboard的UIControls

希望能帮助你… !!!

我喜欢下面的技术的原因,因为它也帮助我确定表的部分。

在单元格中添加buttoncellForRowAtIndexPath:

  UIButton *selectTaskBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [selectTaskBtn setFrame:CGRectMake(15, 5, 30, 30.0)]; [selectTaskBtn setTag:indexPath.section]; //Not required but may find useful if you need only section or row (indexpath.row) as suggested by MR.Tarun [selectTaskBtn addTarget:self action:@selector(addTask:) forControlEvents:UIControlEventTouchDown]; [cell addsubview: selectTaskBtn]; 

事件addTask:

 -(void)addTask:(UIButton*)btn { CGPoint buttonPosition = [btn convertPoint:CGPointZero toView:self.tableView]; NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition]; if (indexPath != nil) { int currentIndex = indexPath.row; int tableSection = indexPath.section; } } 

希望这有助于。

Swift 2.2

您需要添加该button的目标。

 myButton.addTarget(self, action: #selector(ClassName.FunctionName(_:), forControlEvents: .TouchUpInside) 

FunctionName:连接 //例如

当然你需要设置该button的标签,因为你正在使用它。

 myButton.tag = indexPath.row 

你可以通过inheritanceUITableViewCell来实现这一点。 在界面生成器中使用它,在该单元上放下一个button,通过sockets连接,然后就可以了。

要在连接的function中获得标签:

 func connected(sender: UIButton) { let buttonTag = sender.tag // Do any additional setup } 

塔伦的代码不能在iOS7上工作,因为UITableViewCell结构改变了,现在他会得到“UITableViewCellScrollView”。

这篇文章在iOS 7中使用superview获取UITableViewCell有一个很好的解决scheme,创build一个循环来查找正确的父视图,而不pipe将来的结构变化如何。 它归结为创build一个循环:

  UIView *superView = [sender superview]; UIView *foundSuperView = nil; while (nil != superView && nil == foundSuperView) { if ([superView isKindOfClass:[UITableViewCell class]]) { foundSuperView = superView; } else { superView = superView.superview; } } 

该链接有一个更可重用的解决scheme的代码,但这应该工作。

我发现在你的单元格内部button的子类最简单(Swift 3):

 class MyCellInfoButton: UIButton { var indexPath: IndexPath? } 

在你的单元格类中:

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

在表视图或集合视图的数据源中,当出现单元格时,将button的索引path:

 cell.infoButton.indexPath = indexPath 

所以你可以把这些代码放到你的表格视图控制器中:

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

不要忘记在Interface Builder中设置button的类,并将其链接到handleTapOnCellInfoButton函数!


编辑:

使用dependency injection。 设置调用闭包:

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

并在集合视图的委托的willDisplay方法中注入闭包:

  func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { (cell as? MyCell)?.someFunction = { print(indexPath) // Do something with the indexPath. } } 

Swift 3closures

一个很好的解决scheme是在自定义的UITableViewCell中使用闭包来callbackviewController的动作。

在单元格中:

 final class YourCustomCell: UITableViewCell { var callbackClosure: (() -> Void)? // Configure the cell here func configure(object: Object, callbackClosure: (() -> Void)?) { self.callbackClosure = callbackClosure } // MARK: - IBAction extension YourCustomCell { @IBAction fileprivate func actionPressed(_ sender: Any) { guard let closure = callbackClosure else { return } closure() } } 

在视图控制器:表视图委托

 extension YourViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { guard let cell: YourCustomCell = cell as? YourCustomCell else { return } cell.configure(object: object, callbackClosure: { [weak self] in self?.buttonAction() }) } } fileprivate extension YourViewController { func buttonAction() { // do your actions here } } 

@Mani的答案是好的,但是单元格内容视图内的标签通常被用于其他目的。 你可以使用单元格的标签(或单元格的contentView标签):

1)在你的cellForRowAtIndexPath:方法中,将单元格的标签指定为索引:

 cell.tag = indexPath.row; // or cell.contentView.tag... 

2)为你的button添加目标和动作如下:

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

3)创build返回发件人行的方法(谢谢@Stenio Ferreira):

 - (NSInteger)rowOfSender:(id)sender { UIView *superView = sender.superview; while (superView) { if ([superView isKindOfClass:[UITableViewCell class]]) break; else superView = superView.superview; } return superView.tag; } 

4)基于索引的代码操作:

 -(void)yourButtonClicked:(UIButton*)sender { NSInteger index = [self rowOfSender:sender]; // Your code here } 

CustomTableCell.h是一个UITableViewCell:

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

导入后MyVC.m:

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

在MyVC.m的“cellForRowAtIndexPath”里面:

 //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]; } 
 cell.show.tag=indexPath.row; [cell.show addTarget:self action:@selector(showdata:) forControlEvents:UIControlEventTouchUpInside]; -(IBAction)showdata:(id)sender { UIButton *button = (UIButton *)sender; UIStoryboard *storyBoard; storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; SecondViewController *detailView = [storyBoard instantiateViewControllerWithIdentifier:@"SecondViewController"]; detailView.string=[NSString stringWithFormat:@"%@",[_array objectAtIndex:button.tag]]; [self presentViewController:detailView animated:YES completion:nil]; }