我有一个内有按钮的单元格。在我的cellForRowAtIndexPath方法中,我以这种方式回到我的uibutton:
UIButton *Button= (UIButton *) [cell viewWithTag:3];
我找到了一个解决方案,如下所示:
Button.tag = indexPath.row;
[Button addTarget:self action:@selector(yourButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
-(void)yourButtonClicked:(UIButton*)sender
{
if (sender.tag == 0)
{
// Your code here
}
}
但我的button.tag已用于从单元格内的其他视图中识别UI按钮视图,我无法将其用于indexpath.row。我的情况怎么办?
修改
最后我为UIButton制作了一个类别,它似乎是更快的可重用广告解决方案,但这里的每个答案都是有效的选项
答案 0 :(得分:1)
您无需使用标记访问该按钮,然后为每个单元格设置Selector
。我相信你可以实现更清洁的方法
第1步:
在“自定义”单元格中,将IBAction
从单元格中的按钮拖到自定义单元格中。
@IBAction func buttonTapped(_ sender: Any) {
//wait for implementation
}
第2步:
在您的自定义单元格中,现在声明一个协议
protocol CellsProtocol : NSObjectProtocol {
func buttonTapped(at index : IndexPath)
}
并且在同一个班级时,也要创建一些变量。
weak var delegate : CellsProtocol? = nil
var indexPath : IndexPath! = nil
我们很快就会看到这些变量的用法:)
第3步:
让我们回到刚刚拖动的IBAction
@IBAction func buttonTapped(_ sender: Any) {
self.delegate?.buttonTapped(at: self.indexPath)
}
第4步:
现在您可以回到UITableViewController
并确认刚刚宣布的协议
extension ViewController : CellsProtocol {
func buttonTapped(at index: IndexPath) {
//here you have indexpath of cell whose button tapped
}
}
第5步:
现在最终将您的cellForRowAtIndexPath
更新为
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : MyTableViewCell = ;
cell.indexPath = indexPath
cell.delegate = self
}
}
多数民众赞成:)现在你有一个按钮动作告诉你,按钮在哪个单元格中点击:)希望它有所帮助:)这是更通用的方法,因为即使你有多个uicomponents
你仍然可以使用这种方法。
编辑1:
在下面的评论rmaddy中指出将indexPath作为属性单元格可能会导致问题,并且单元格不应该知道它的indexPath和协议应该被修改以返回单元格而不是返回索引路径。
引用评论:
不一定。您假设正在调用reloadData。您可以 有一个可见的单元格,然后在它上面插入一行。那个可见的细胞 没有更新,它的indexPath与单元格没有区别 您拥有的indexPath属性未更新。使用单元格本身 作为论点。它比传递索引路径好得多。如果 委托需要索引路径,委托可以询问表 查看单元格的当前索引路径。细胞永远不应该关心 或者知道它的索引路径是什么。
上面的陈述特别有道理,A小区永远不应该关心或知道它的索引路径是什么。因此,请在下面更新我的答案
第1步:
继续并删除单元格中的indexPath属性:
第2步:
将协议修改为
protocol CellsProtocol : NSObjectProtocol {
func buttonTapped(in cell : UITableViewCell)
}
第3步:
将您的IBAction修改为
@IBAction func buttonTapped(_ sender: Any) {
self.delegate?.buttonTapped(in: self)
}
第4步:
最后将ViewController中的协议确认修改为
extension ViewController : CellsProtocol {
func buttonTapped(in cell: UITableViewCell) {
let indexPath = self.tableView.indexPath(for: cell)
//here you have indexpath of cell whose button tapped
}
}
多数民众赞成:)
答案 1 :(得分:1)
创建UIButton的自定义按钮子类,并根据需要定义属性。 Button.tag是默认标识符。在自定义类中,您可以根据需要提供尽可能多的属性。然后使用此自定义按钮类而不是UIButton。用户自定义属性后跟点(。),就像标记一样。
答案 2 :(得分:1)
另一种选择 - 使用“回拨”块。
这假设您有一个带有“btnCell”标识符的Prototype单元格,其中包含连接到下面显示的- (IBAction)buttonTapped:(id)sender
方法的UIButton ...
你的细胞类:
//
// WithButtonTableViewCell.h
//
// Created by Don Mag on 11/15/17.
//
#import <UIKit/UIKit.h>
@interface WithButtonTableViewCell : UITableViewCell
- (void)setButtonTappedBlock:(void (^)(id sender))buttonTappedBlock;
@end
//
// WithButtonTableViewCell.m
//
// Created by Don Mag on 11/15/17.
//
#import "WithButtonTableViewCell.h"
@interface WithButtonTableViewCell ()
@property (copy, nonatomic) void (^buttonTappedBlock)(id sender);
@end
@implementation WithButtonTableViewCell
- (IBAction)buttonTapped:(id)sender {
// call back if the block has been set
if (self.buttonTappedBlock) {
self.buttonTappedBlock(self);
}
}
@end
您的表视图控制器类:
//
// WithButtonTableViewController.h
//
// Created by Don Mag on 7/12/17.
//
#import <UIKit/UIKit.h>
@interface WithButtonTableViewController : UITableViewController
@end
//
// WithButtonTableViewController.m
//
// Created by Don Mag on 11/15/17.
//
#import "WithButtonTableViewController.h"
#import "WithButtonTableViewCell.h"
@interface WithButtonTableViewController ()
@end
@implementation WithButtonTableViewController
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
WithButtonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"btnCell" forIndexPath:indexPath];
[cell setButtonTappedBlock:^(id sender) {
NSLog(@"Button in cell at row %ld in section: %ld was tapped", (long)indexPath.row, (long)indexPath.section);
// sender is the cell
// do whatever else you want here...
}];
return cell;
}
@end
现在,当点击单元格中的按钮时,它将“回调”到视图控制器,此时块内的代码将被执行。