iPhone-如何确定自定义UITableViewCell中按下按钮的单元格

iPhone-如何确定自定义UITableViewCell中按下按钮的单元格,iphone,uitableview,uibutton,Iphone,Uitableview,Uibutton,我目前有一个UITableView,其中填充了一个单独nib中的自定义UITableViewCell。在单元格中,有两个按钮连接到自定义单元格类中的操作。当我单击其中一个按钮时,我可以调用适当的方法,但我需要知道按钮按入了哪一行。每个按钮的标记属性为0。我不需要知道整个单元格何时被选中,只需要按下一个特定的按钮,所以我需要知道它是哪一行,这样我就可以更新适当的对象。您可以使用按钮上的标记属性来指定按钮是在哪一行创建的,如果您没有将标记用于任何其他内容。您可以访问按钮superview以获取包含按

我目前有一个UITableView,其中填充了一个单独nib中的自定义UITableViewCell。在单元格中,有两个按钮连接到自定义单元格类中的操作。当我单击其中一个按钮时,我可以调用适当的方法,但我需要知道按钮按入了哪一行。每个按钮的标记属性为0。我不需要知道整个单元格何时被选中,只需要按下一个特定的按钮,所以我需要知道它是哪一行,这样我就可以更新适当的对象。

您可以使用按钮上的
标记属性来指定按钮是在哪一行创建的,如果您没有将标记用于任何其他内容。

您可以访问按钮
superview
以获取包含按钮的
UITableViewCell
,但是如果您只需要行号,您可以像前面的post-deacripes一样使用
标记
属性。

我有相同的场景。为此,我派生了一个自定义单元格。我添加了两个属性,section和row。我还添加了一个所有者,它将是我的派生TableViewController类。当需要单元格时,我根据indexPath和所有者设置节/行

cell.section=indexPath.section cell.row=indexPath.row cell.owner=self


我做的下一件事是在创建按钮时,将按钮事件与单元格关联,而不是与tableViewController关联。事件处理程序可以读取节和行条目,并将适当的消息(或事件)发送到TableViewController。通过利用现有的方法和内务管理,并尽可能保持单元的独立性,这大大简化了内务管理和维护。既然系统已经跟踪细胞了,为什么还要跟踪两次呢

更简单的解决方案是使用(id)sender定义按钮回调,并使用它来挖掘表行索引。下面是一些示例代码:

- (IBAction)buttonWasPressed:(id)sender
{
    NSIndexPath *indexPath =
        [self.myTableView
         indexPathForCell:(UITableViewCell *)[[sender superview] superview]];
    NSUInteger row = indexPath.row;

    // Do something with row index
}
很可能您使用了相同的行索引来创建/填充单元格,因此确定按钮现在应该做什么应该很简单。不需要玩标签,并试图保持他们的秩序

澄清:如果您当前使用-(iAction)按钮已按下;只需将其重新定义为-(iAction)按钮已压缩:(id)发送方;附加的回调参数在那里,不需要做任何额外的事情来获得它。还记得将按钮重新连接到Interface Builder中的新回调

更容易:

-(IBAction) buttonPressed {
    NSIndexPath *myIndexPath = [(UITableView *)self.superview indexPathForCell: self];
    // do whatever you need to do with the information
}

有多种方法可以解决此问题

  • 您可以使用“标记”属性 将值indexPath.row作为按钮的标记值。
    btn.tag=indexPath.row 然后在按钮功能中,您可以轻松访问标记值,它将成为单击按钮的索引

    -(void)btnClicked:(id)sender
    {
        int index = [sender tag];
    }
    
  • 可以使用图层特性 添加indexPath作为层字典中的值

    [[btn layer]setValue:indepath-forKey:@“indepath”]

  • 可以通过按钮操作函数访问此indexPath

    -(void)btnClicked:(id)sender
    {
        NSIndexPath *indexPath = [[sender layer] valueForKey:@"indexPath"];
        int index = indexPath.row;
    }
    

    使用此方法,只需在字典中添加具有不同键的新对象,即可将多个值传递给按钮函数。

    对于不依赖于标记或视图层次结构的实现,请执行以下操作

    - (void)btnPressed:(id)sender event:(id)event
    {
      UITouch *touch = [[event allTouches] anyObject];
      CGPoint touchPoint = [touch locationInView:self.tableView];
      NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPoint];
    }
    

    此解决方案也适用于使用故事板单元原型连接的iAction

    - (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);
    }
    

    这里有一个快速的例子

    UIControl类是各种iOS小部件的超类,包括UIButton,因为UIControl提供发送事件通知的目标/操作机制。因此,处理此问题的一般方法如下:

    func actionHandler(control: UIControl)
       var indexPath = tableView.indexPathForCell(control.superview!.superview! as UITableViewCell)!
       var row = indexPath.row
    }
    
    下面是一个设置按钮控件以传递操作的示例。或者,创建@iAction并使用Interface Builder可视化地创建该动作

    button.addTarget(self, action: "actionHandler:", forControlEvents: .TouchUpInside)
    
    您可以将UIControl参数向下转换为UIButton、UIStepper等。。。必要时。例如:

    var button = control as UIButton
    

    控件的superview是UITableViewCell的contentView,其子视图是单元格中显示的UIView(UIControl是UIView的子类)。内容单元格的superview是UITableViewCell本身。这就是为什么这是一种可靠的机制,可以不受惩罚地遍历SuperView。

    我是否需要在CellForRowatineXpath方法中设置标记,然后在按下按钮时访问它?是的,这是最好的方法。我已经寻找了很长时间,因为我也是新手。感谢@pix0r提供的好建议。请注意,如果您的表中有多个分区,并且所有分区的按钮都链接了相同的操作,那么这将没有多大帮助。使用[sender superview];在自定义单元格类(包含按钮的操作方法)中,为我提供了一个UIView,而不是单元格。如果我在cellForRowAtIndexPath方法中设置标记,当按下单元格中的每个按钮时,标记仍然是0。没错,你需要使用另一篇文章中描述的[[sender superview]superview]。。这就是单元格,包含UIView,其中包含你的按钮。这是一个很好的解决方案:当然你可以重用单元格,如果用例允许的话!否则事情会变得非常复杂。无论如何,添加到tableView的第一行将是“第一行”。对不起,我看这没什么问题?请澄清我孤独的“重用单元”评论。这是对另一条评论的回应,该评论现已被某人删除。我也投了反对票!不用担心,我会活下来的:)我只是抓取了这个动作的内容,以确定哪个UITableView单元格中的哪个按钮调用了Segue。这个技巧在那里也很棒!“[sender superview]superview]”在iOS 7中不再适用于我。在找到UITableViewCell类之前,应该循环超级视图。这是一个多么可怕的黑客行为。图层不是用来存储任意数据的。有关更好的解决方案,请参阅。@tinku George-您的第一个答案在我的案例中起了作用!。谢谢谢谢你的回答!它在我的电脑上工作
    var button = control as UIButton