【问题标题】:iPhone - How to determine in which cell a button was pressed in a custom UITableViewCelliPhone - 如何确定在自定义 UITableViewCell 中按下按钮的单元格
【发布时间】:2010-11-05 00:11:54
【问题描述】:

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

【问题讨论】:

    标签: iphone uitableview uibutton


    【解决方案1】:

    您可以使用按钮上的tag 属性来指定创建按钮的行,如果您不使用其他任何标签。

    【讨论】:

    • 是否需要在cellForRowAtIndexPath方法中设置标签,然后在按下按钮时访问?
    • 是的,这是最好的方法。
    • 找这个很久了,因为我也是新手。感谢@pix0r 的好建议。
    • 请注意,如果您的表格有多个部分都具有链接到其按钮的相同操作,这将没有多大帮助。
    【解决方案2】:

    您可以访问按钮superview 以获取包含您的按钮的UITableViewCell,但如果您只需要行号,则可以使用tag 属性,就像上一篇文章描述的那样。

    【讨论】:

    • 使用 [sender superview];在自定义单元格类(包含按钮的操作方法)中给了我一个 UIView,而不是单元格。如果我在 cellForRowAtIndexPath 方法中设置标签,按下时单元格中的每个按钮仍然为 0。
    • 没错,你需要使用 [[sender superview] superview] ,正如另一篇文章中描述的那样……这就是单元格,包含一个 UIView,其中包含你的按钮。
    • 这是一个很好的解决方案:71squared.com/2008/12/…
    【解决方案3】:

    我有同样的情况。为此,我派生了一个自定义单元格。我添加了两个属性,section 和 row。我还添加了一个所有者,这将是我派生的 TableViewController 类。当请求单元格时,我会根据 indexPath 以及所有者设置部分/行。

    cell.section = indexPath.section cell.row = indexPath.row cell.owner = 自我

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

    【讨论】:

      【解决方案4】:

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

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

      您很可能使用相同的行索引来创建/填充单元格,因此确定您的按钮现在应该做什么应该是微不足道的。无需玩标签并尽量保持它们井井有条!

      澄清:如果您当前使用-(IBAction)buttonWasPressed;只需将其重新定义为-(IBAction)buttonWasPressed:(id)sender; 额外的回调参数就在那里,不需要做任何额外的事情来获取它。还记得将您的按钮重新连接到 Interface Builder 中的新回调!

      【讨论】:

      • 当然,如果用例允许,您可以重复使用单元格!否则事情会变得非常复杂。无论如何,添加到 tableView 的第一行将是“第一行”。抱歉,我认为这没有问题?
      • 澄清我孤独的“重用细胞”评论。这是对另一条评论的回应,该评论现在已被某人删除。我也对此投了反对票!别担心,我会活下来的:)
      • 我刚刚抓取了这个动作的内容来处理确定哪个按钮在哪个 UITableView 单元格中调用了 Segue。这种技术在那里也很棒!
      • "[sender superview] superview]" 在 iOS 7 中不再适用于我。
      • 应该遍历超级视图直到找到 UITableViewCell 类
      【解决方案5】:

      更简单:

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

      【讨论】:

        【解决方案6】:

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

        1. 您可以使用“标签”属性 将值 indexPath.row 作为按钮的标记值。
          btn.tag = indexPath.row;

        然后在按钮功能中,您可以轻松访问标签值,它将成为点击按钮的索引。

        -(void)btnClicked:(id)sender
        {
            int index = [sender tag];
        }
        
        1. 您可以使用图层属性 将 indexPath 添加为图层字典中的值。

          [[btn layer] setValue:indexPath forKey:@"indexPath"];

        此 indexPath 可从按钮操作函数访问。

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

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

        【讨论】:

        • 多么可怕的黑客攻击。层不能存储任意数据。
        • 请参阅stackoverflow.com/questions/9274494/… 以获得更好的解决方案。
        • @tinku George - 你的第一个答案在我的情况下有效!。谢谢!
        【解决方案7】:

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

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

        【讨论】:

          【解决方案8】:
              [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]]
          }
          

          【讨论】:

            【解决方案9】:

            此解决方案也适用于使用情节提要单元原型连接的 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);
            }
            

            【讨论】:

              【解决方案10】:

              这是一个 Swift 示例...

              UIControl 类是包括 UIButton 在内的各种 iOS 小部件的超类,因为 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
              

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

              【讨论】:

              • 感谢您的精彩回答!它适用于同一行中UITableView 中的多个按钮!
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-02-24
              • 2012-03-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-03-23
              • 1970-01-01
              相关资源
              最近更新 更多