ios 在 UITableViewCell 中获取按钮单击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20655060/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get button click inside UITableViewCell
提问by ankit_rck
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
.
所以,我有ViewController.h
和ViewController.m
在那里我有UITableView
和TableTemplate.h
,TableTemplate.m
和TableTemplate.xib
在那里我有定义的笔尖。我想要带有单元格索引的按钮单击事件ViewController.m
。
Any help on how can I do that?
关于我该怎么做的任何帮助?
回答by Mani
1) In your cellForRowAtIndexPath:
method, assign button tag as index:
1)在您的cellForRowAtIndexPath:
方法中,将按钮标签指定为索引:
cell.yourbutton.tag = indexPath.row;
2) Add target and action for your button as below:
2)为您的按钮添加目标和操作,如下所示:
[cell.yourbutton addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
3) Code actions based on index as below in ViewControler
:
3)基于索引的代码操作如下ViewControler
:
-(void)yourButtonClicked:(UIButton*)sender
{
if (sender.tag == 0)
{
// Your code here
}
}
Updates for multiple Section:
多个部分的更新:
You can check this linkto detect button click in table view for multiple row and section.
您可以检查此链接以检测表视图中多行和部分的按钮单击。
回答by GoodSp33d
Delegates are the way to go.
代表是要走的路。
As seen with other answers using views might get outdated. Who knows tomorrow there might be another wrapper and may need to use cell superview]superview]superview]superview]
. And if you use tags you would end up with n number of if else conditions to identify the cell. To avoid all of that set up delegates. (By doing so you will be creating a re usable cell class. You can use the same cell class as a base class and all you have to do is implement the delegate methods.)
正如使用视图的其他答案所见,可能会过时。谁知道明天可能会有另一个包装器并且可能需要使用cell superview]superview]superview]superview]
. 如果你使用标签,你最终会得到 n 个 if else 条件来识别单元格。为了避免所有这些设置代表。(通过这样做,您将创建一个可重用的单元类。您可以使用相同的单元类作为基类,您所要做的就是实现委托方法。)
First we need a interface (protocol) which will be used by cell to communicate(delegate) button clicks. (You can create a separate .h file for protocol and include in both table view controller and custom cell classes OR just add it in custom cell class which will anyway get included in table view controller)
首先,我们需要一个接口(协议),它将被单元用来通信(委托)按钮点击。(您可以为协议创建一个单独的 .h 文件并包含在表格视图控制器和自定义单元格类中,或者只需将其添加到自定义单元格类中,无论如何都会包含在表格视图控制器中)
@protocol CellDelegate <NSObject>
- (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data;
@end
Include this protocol in custom cell and table view controller. And make sure table view controller confirms to this protocol.
将此协议包含在自定义单元格和表格视图控制器中。并确保表视图控制器确认此协议。
In custom cell create two properties :
在自定义单元格中创建两个属性:
@property (weak, nonatomic) id<CellDelegate>delegate;
@property (assign, nonatomic) NSInteger cellIndex;
In UIButton
IBAction delegate click : (Same can be done for any action in custom cell class which needs to be delegated back to view controller)
在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"];
}
}
In table view controller cellForRowAtIndexPath
after dequeing the cell, set the above properties.
在cellForRowAtIndexPath
单元格出列后的表视图控制器中,设置上述属性。
cell.delegate = self;
cell.cellIndex = indexPath.row; // Set indexpath if its a grouped table.
And implement the delegate in table view controller:
并在表视图控制器中实现委托:
- (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data
{
// Do additional actions as required.
NSLog(@"Cell at Index: %d clicked.\n Data received : %@", cellIndex, data);
}
This would be the ideal approach to get custom cell button actions in table view controller.
这将是在表格视图控制器中获取自定义单元格按钮操作的理想方法。
回答by Maciej Chrzastek
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 :)
我没有使用标签,而是采用了不同的方法。为我的 UITableViewCell(OptionButtonsCell) 子类做了委托,并添加了一个 indexPath 变量。从故事板中的按钮,我将@IBAction 连接到 OptionButtonsCell,然后我将带有正确 indexPath 的委托方法发送给任何感兴趣的人。在索引路径的单元格中,我设置了当前的 indexPath 并且它有效:)
Let the code speak for itself:
让代码不言自明:
Swift 3 Xcode 8
斯威夫特 3 Xcode 8
OptionButtonsTableViewCell.swift
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
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)")
}
回答by Tarun
This should help :-
这应该有帮助:-
UITableViewCell* cell = (UITableViewCell*)[sender superview];
NSIndexPath* indexPath = [myTableView indexPathForCell:cell];
Here senderis the UIButton instance that is sending the event. myTableViewis the UITableView instance you're dealing with.
这里的sender是发送事件的 UIButton 实例。 myTableView是您正在处理的 UITableView 实例。
Just get the cell reference right and all the work is done.
只需正确获取单元格引用即可完成所有工作。
You may need to remove the buttons from cell's contentView & add them directly to UITableViewCell instance as it's subview.
您可能需要从单元格的 contentView 中删除按钮并将它们直接添加到 UITableViewCell 实例,因为它是子视图。
Or
或者
You can formulate a tag naming scheme for different UIButtons in cell.contentView. Using this tag, later you can know the row & section information as needed.
您可以在 cell.contentView 中为不同的 UIButton 制定标签命名方案。使用这个标签,以后可以根据需要知道行&节信息。
回答by Piyush
Following code might Help you.
以下代码可能对您有所帮助。
I have taken UITableView
with custom prototype cell class named UITableViewCell
inside UIViewController
.
我采用UITableView
了名为UITableViewCell
inside 的自定义原型单元类UIViewController
。
So i have ViewController.h
, ViewController.m
and TableViewCell.h
,TableViewCell.m
所以我有ViewController.h
,ViewController.m
并且TableViewCell.h
,TableViewCell.m
Here is the code for that:
这是代码:
ViewController.h
ViewController.h
@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tblView;
@end
ViewController.m
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;
}
Custom cell class :
自定义单元类:
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
and
和
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);
}
}
Note: Here I have taken all UIControls
using Storyboard.
注意:这里我UIControls
使用了 Storyboard。
Hope that can help you...!!!
希望能帮到你。。。!!!
回答by Yogesh Lolusare
The reason i like below technique because it also help me to identify the section of table.
我喜欢下面的技术的原因是因为它也帮助我识别表格的部分。
Add Button in cell cellForRowAtIndexPath:
在单元格 cellForRowAtIndexPath 中添加按钮:
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];
Event 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;
}
}
Hopes this help.
希望这有帮助。
回答by valexa
Use Swift closures :
使用 Swift 闭包:
class TheCell: UITableViewCell {
var tapCallback: (() -> Void)?
@IBAction func didTap(_ sender: Any) {
tapCallback?()
}
}
extension TheController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TheCell.identifier, for: indexPath) as! TheCell {
cell.tapCallback = {
//do stuff
}
return cell
}
}
回答by Stenio Ferreira
Tarun's code doesnt work on iOS7, since the UITableViewCell structure changed and now he would get "UITableViewCellScrollView" instead.
Tarun 的代码在 iOS7 上不起作用,因为 UITableViewCell 结构发生了变化,现在他会得到“UITableViewCellScrollView”。
This post Getting UITableViewCell with superview in iOS 7has a good solution creating a loop to find the correct parent view, regardless of any future changes in the structure. It boils down to creating a loop:
这篇文章在 iOS 7 中使用 superview 获取 UITableViewCell有一个很好的解决方案,即创建一个循环来找到正确的父视图,而不管未来的结构发生任何变化。它归结为创建一个循环:
UIView *superView = [sender superview];
UIView *foundSuperView = nil;
while (nil != superView && nil == foundSuperView) {
if ([superView isKindOfClass:[UITableViewCell class]]) {
foundSuperView = superView;
} else {
superView = superView.superview;
}
}
The link has code for a more reusable solution, but this should work.
该链接具有更可重用解决方案的代码,但这应该有效。
回答by Himanshu padia
Swift 2.2
斯威夫特 2.2
You need to add target for that button.
您需要为该按钮添加目标。
myButton.addTarget(self, action: #selector(ClassName.FunctionName(_:), forControlEvents: .TouchUpInside)
FunctionName: connected// for example
函数名称:已连接// 例如
And of course you need to set tag of that button since you are using it.
当然,您需要设置该按钮的标签,因为您正在使用它。
myButton.tag = indexPath.row
You can achieve this by subclassing UITableViewCell. Use it in interface builder, drop a button on that cell, connect it via outlet and there you go.
您可以通过继承 UITableViewCell 来实现这一点。在界面生成器中使用它,在该单元格上放一个按钮,通过插座连接它,然后就可以了。
To get the tag in the connected function:
要在连接的函数中获取标签:
func connected(sender: UIButton) {
let buttonTag = sender.tag
// Do any additional setup
}
回答by Yogesh Tarsariya
Its Work For me.
它为我工作。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UIButton *Btn_Play = (UIButton *)[cell viewWithTag:101];
[Btn_Play addTarget:self action:@selector(ButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(void)ButtonClicked:(UIButton*)sender {
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.Tbl_Name];
NSIndexPath *indexPath = [self.Tbl_Name indexPathForRowAtPoint:buttonPosition];
}