我目前有一个 UITableView,它填充了一个单独的 nib 中的自定义 UITableViewCell。在单元格中,有两个按钮连接到自定义单元格类中的操作。当我单击其中一个按钮时,我可以调用正确的方法,但我需要知道按钮被按下的是哪一行。每个按钮的标记属性为 0。我不需要知道整个单元格的时间被选中,只是在按下特定按钮时,所以我需要知道它是哪一行,以便我可以更新正确的对象。
10 回答
Much easier solution is to define your button callback with (id)sender and use that to dig out the table row index. Here's some sample code:
- (IBAction)buttonWasPressed:(id)sender
{
NSIndexPath *indexPath =
[self.myTableView
indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
NSUInteger row = indexPath.row;
// Do something with row index
}
Most likely you used that same row index to create/fill the cell, so it should be trivial to identify what your button should now do. No need to play with tags and try to keep them in order!
Clarification: if you currently use -(IBAction)buttonWasPressed; just redefine it as -(IBAction)buttonWasPressed:(id)sender; The additional callback argument is there, no need to do anything extra to get it. Also remember to reconnect your button to new callback in Interface Builder!
tag
如果您没有将标签用于其他任何内容,则可以使用按钮上的属性来指定创建按钮的行。
对于不依赖于标签或视图层次结构的实现,请执行以下操作
- (void)btnPressed:(id)sender event:(id)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPoint];
}
我有同样的情况。为此,我派生了一个自定义单元格。我添加了两个属性,section 和 row。我还添加了一个所有者,这将是我派生的 TableViewController 类。当请求单元格时,我根据 indexPath 以及所有者设置节/行。
cell.section = indexPath.section cell.row = indexPath.row cell.owner = self
我做的下一件事是当我创建按钮时,我将按钮事件与单元格而不是与 tableViewController 相关联。事件处理程序可以读取节和行条目并将适当的消息(或事件)发送到 TableViewController。这通过利用现有方法和内务管理并尽可能地保持单元独立,极大地简化了内务管理和维护。既然系统已经跟踪了细胞,为什么要重复两次!
这是一个斯威夫特的例子......
UIControl 类是各种 iOS 小部件(包括 UIButton)的超类,因为 UIControl 提供了发送事件通知的目标/动作机制。因此,处理此问题的通用方法如下:
func actionHandler(control: UIControl)
var indexPath = tableView.indexPathForCell(control.superview!.superview! as UITableViewCell)!
var row = indexPath.row
}
这是一个设置按钮控件以传递操作的示例。或者,创建一个 @IBAction 并使用 Interface Builder 直观地创建操作。
button.addTarget(self, action: "actionHandler:", forControlEvents: .TouchUpInside)
您可以根据需要将 UIControl 参数向下转换为 UIButton、UIStepper 等。例如:
var button = control as UIButton
control的superview是UITableViewCell的contentView,其子view是cell中显示的UIView(UIControl是UIView的子类)。内容单元格的父视图是 UITableViewCell 本身。这就是为什么这是一个可靠的机制,并且可以不受惩罚地遍历超级视图。
更容易:
-(IBAction) buttonPressed {
NSIndexPath *myIndexPath = [(UITableView *)self.superview indexPathForCell: self];
// do whatever you need to do with the information
}
您可以访问按钮superview
以获取UITableViewCell
包含您的按钮的按钮,但如果您只需要行号,则可以使用tag
上一篇文章中描述的属性。
有多种方法可以解决问题。
- 您可以使用“tag”属性将值 indexPath.row 作为按钮的标记值。
btn.tag = indexPath.row;
然后在按钮功能中,您可以轻松访问标签值,它将成为单击按钮的索引。
-(void)btnClicked:(id)sender
{
int index = [sender tag];
}
您可以使用图层属性添加 indexPath 作为图层字典中的值。
[[btn 层] setValue:indexPath forKey:@"indexPath"];
此 indexPath 可从按钮操作函数访问。
-(void)btnClicked:(id)sender
{
NSIndexPath *indexPath = [[sender layer] valueForKey:@"indexPath"];
int index = indexPath.row;
}
使用此方法,您只需在字典中添加具有不同键的新对象即可将多个值传递给按钮功能。
此解决方案也适用于使用情节提要单元原型连接的 IBAction
- (IBAction)viewMapPostsMarker:(UIButton*)sender{
// button > cellContentView > cellScrollView > cell
UITableViewCell *cell = (UITableViewCell *) sender.superview.superview.superview;
NSIndexPath *index = [self.mapPostsView indexPathForCell:cell];
NSLog(@" cell at index %d",index.row);
}
[btnFavroite setAccessibilityValue:[NSString stringWithFormat:@"%d",indexPath.row]];
[btnFavroite setAccessibilityLabel:btnFavroite.titleLabel.text];
[btnFavroite addTarget:self action:@selector(btnFavClick:) forControlEvents:UIControlEventTouchUpInside];
-(void)btnFavClick:(id)sender{
UIButton *btn=(UIButton *)sender;
int index=[btn.accessibilityValue integerValue]]
}