【问题标题】:Custom UITableView Cell with UIButton not Calling didSelectRowAtIndexPath带有 UIButton 的自定义 UITableView 单元不调用 didSelectRowAtIndexPath
【发布时间】:2014-11-30 03:18:27
【问题描述】:

我知道这可能会发生,但我无法找到在点击按钮时调用此方法的方法。该方法被调用但选择了错误的单元格。

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
_postCell = (postCell *) [self.tableView dequeueReusableCellWithIdentifier:@"postCell"];
_postCell.personStringPost.text = [object objectForKey:@"stringPost"];
[_postCell.nameLabel setTitle:[object objectForKey:@"User_Name"]  forState:UIControlStateNormal];
_postCell.userId = [object objectForKey:@"userId"];
_postCell.selectionStyle = UITableViewCellSelectionStyleNone;

PFFile *imageFile = [object objectForKey:@"profileImage"];
NSData *data = [imageFile getData];
_postCell.profileImage.image = [UIImage imageWithData:data];

[_postCell.nameLabel addTarget:self action:@selector(personProfile:tableView:) forControlEvents: UIControlEventTouchUpInside];
[_postCell.profileImageButton addTarget:self action:@selector(personProfile:tableView:) forControlEvents:UIControlEventTouchUpInside];

    return _postCell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
postCell *cell = (postCell *)[tableView cellForRowAtIndexPath:indexPath];
self.userId = cell.userId;
NSLog(@"Did Select: %@", self.userId);
}

- (void) personProfile: (NSIndexPath *) indexPath tableView: (UITableView *) tableView{
[self tableView:tableView didSelectRowAtIndexPath:indexPath];
 [self performSegueWithIdentifier:@"personProfile" sender:self];
}

【问题讨论】:

    标签: ios xcode uitableview uibutton


    【解决方案1】:

    希望对你有所帮助

    在处理只有一个部分的按钮时

    in cellfor row 方法

    yourcell.mybutton.tag=indexPath.row;
    
    -(void)myCellbuttonAction:(id)sender
    {
       UIButton *button = (UIButton *)sender; // first, cast the sender to UIButton
      NSInteger row = button.tag; // recover the row
      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
    
      // apply your logic for indexpath  as in didselect row   
    }
    

    在处理多个部分和多行时,这可能会对您有所帮助

    在单元格中用于行方法

    yourcell.tag=indexPath.section;
    yourcell.contentview.tag=indexPath.row;
    

    您的按钮操作可能如下所示

    -(void)myCellbuttonAction:(id)sender
    {
    UIButton *button = (UIButton *)sender; // first, cast the sender to UIButton
    
    id rowid =[button superview];
    id sectionid = [rwoid superview];
    
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[rowid tag] inSection:[sectionid tag]];
    
     // apply your logic for indexpath  as in didselect row   
    }
    

    【讨论】:

      【解决方案2】:

      这里有一些东西。

      a) 我不会在您的 cellForRowAtIndex 方法中使用实例变量 (_postCell)。您可能会遇到细胞重复使用问题,这很可能是您的错误的根源。将其替换为局部变量:

      postcell *cell = (postCell *)[self.tableView dequeueReusableCellWithIdentifier:@"postCell"];
      

      您还需要将所有对_postCell 的引用替换为cell

      b) 请注意,在同一行中,您的演员使用小写 = (postCell *)... - 我在上面做了同样的事情,但最好的做法是类名以大写字母开头。

      c) 你有一个名为nameLabel 的属性,这表明它是UILabel,但你使用的是setTitle:forState: 方法,这意味着它是UIButton。我会重命名这个属性,因为如果名称与类匹配(或者至少不暗示错误的类),调试会容易得多。

      d) 当你调用addTarget:action:forControlEvents 方法时,你的选择器是personProfile:tableView:。该方法的签名用于 NSIndexPath 和 UITableView。但是您的按钮不会发送这些类型的参数。它将发送发件人的详细信息 - 即触发操作的按钮。因此,您需要修改您的方法以接受该类型的参数:

      [cell.nameLabel addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];
      

      e) 当方法被调用时,您需要一种方法来确定发送按钮在哪个单元格上。理想情况下,您可以将 UIButton 子类化以向单元格添加一些链接,但是(如果您只有一个部分)您可能会将行号作为标记而侥幸。为此,请添加:

      cell.nameLabel.tag = indexPath.row;
      

      到您的cellForRowAtIndexPath:。然后你可以实现一个不同的方法来处理按钮按下,如下:

      -(void)buttonPressed:(id)sender {
          UIButton *button = (UIButton *)sender; // first, cast the sender to UIButton
          NSInteger row = button.tag; // recover the row
          NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; // derive the indexPath, assuming section is 0
          [self.tableView selectRowAtIndexPath:indexPath animated:YES]; // select the relevant row in the table (assuming the table is self.tableView)
          [self performSegueWithIdentifier:@"personProfile" sender:self]; // perform the segue
      }
      

      f) 请注意,您不应致电tableView:didSelectRowAtIndexPath:。这是用于在用户选择行时调用的 tableView,而不是用于以编程方式选择行。请改用selectRowAtIndexPath:animated:

      【讨论】:

      • 那行不通。没有错误消息,只是没有工作
      • 究竟什么不起作用?是否选择了错误的单元格?没有选择单元格? didSelectRowAtIndex 会被调用吗?放入一些 NSLogs:buttonPressed: 是否被调用?它是否在selectRowAtIndexPath 中使用了正确的indexPath?
      【解决方案3】:

      这基本上是上面使用 Swift 3

      的 pbasdf 答案

      我确实直接调用 didSelectRowAt,因为它不是由 selectRowAtIndexPath

      触发的

      标签是在创建单元格时使用索引路径的行设置的

      getTableView函数是我自己的

      @IBAction func actionButtonPushed(_ sender: Any) {
          guard let button = sender as? UIButton else { return }
          guard let tableView = getTableView() else { return }
          let indexPath = IndexPath(row: button.tag, section: 0)
          tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
          if let delegate = tableView.delegate {
            delegate.tableView!(tableView, didSelectRowAt: indexPath)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        相关资源
        最近更新 更多