在单元格中单击时,tableView:indexPathForCell 返回 nil

Posted

技术标签:

【中文标题】在单元格中单击时,tableView:indexPathForCell 返回 nil【英文标题】:tableView:indexPathForCell returns nil when clicking in cell 【发布时间】:2017-01-25 16:18:37 【问题描述】:

我知道当单元格被隐藏时 indexPath 会返回 nil,但我的问题是为什么它不可见?

我的情况是: 单击按钮时单元格中有一个按钮,它会尝试获取indexPath(通过选择器indexPathForCell:)

同时tableview被另一个线程刷新。

有时 indexPath 会为零,我的问题是因为按钮在单元格中,当触发事件时,单元格必须存在(否则应该如何单击按钮),导致单元格隐藏的原因是什么?

谢谢。


//Cell.m
@property (nonatomic, weak) UIButton   *button;
@property (nonatomic, weak) XXXDelegate   *delegate;

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

    UIButton * button = xxx;
    [self.contentView addSubview:button];

    [button addTarget:self action:@selector(xxxClick:) forControlEvents:UIControlEventTouchUpInside];


-(void)xxxClick:(id)sender
   [self.delegate xxxClick:self];


//Controller.m
-(void)loadView
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    self.tableView.delegate = self;
    [self.tableView registerClass:[Cell class] forCellReuseIdentifier:@"xxx"];
    

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath       
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"xxx" forIndexPath:indexPath];
    //update cell
    cell.delegate = self;
    return cell;


- (void)xxxClick:(UITableViewCell*) cell 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    //indexPath is nil sometimes? why?

而且,tableview 有时会重新加载

【问题讨论】:

您的问题令人困惑。能否提供更多代码? 为什么 self 在这里是单元格,你应该在视图控制器上添加目标 添加一些示例代码,谢谢 您的单元格没有调用[super initWithStyle:]loadView 不会在 self.view 中添加任何内容。所有这些事情都会造成很多问题。 我调用了[super initWithStyle:],上面的代码只是示例,大部分时间运行正常 【参考方案1】:

谢谢各位,我终于得到答案了。

当按钮被触发并且tableview在同一个runloop中为“reloadData”时,“reloadData”导致单元格不可见,“indexPathForCell”将得到nil。

不检查indexPath的值很危险。

【讨论】:

奇怪但真实! indexPathForCell 将始终为 nil,如果之前在同一运行循环迭代中发出 reloadDatareloadRowsAtIndexPaths:withRowAnimation。不过有些明显,因为从 ios10 开始,任何到 table view 的重新加载消息实际上都会延迟到下一个布局传递,在不同的 run loop 迭代上运行。我发现解决此问题的一种方法是将重新加载命令包含在 dispatch_async(dispatch_get_main_queue(), ... 块中。它只是以某种方式工作!【参考方案2】:

您可能会在情节提要的自定义单元格中定义错误的重用标识符。

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell : SingleLabelTableCell = tableView.dequeueReusableCellWithIdentifier("SingleLabelTableCell", forIndexPath: indexPath) as! SingleLabelTableCell
    let tempDict : NSDictionary = dataArray.objectAtIndex(indexPath.row) as! NSDictionary
    cell.nameLabel.text = tempDict.valueForKey("title") as? String
    return cell

或者你也可以在这个视频教程链接上查看它

https://www.youtube.com/watch?v=OHue6nFUBO8

【讨论】:

【参考方案3】:

尝试使用以下格式

Cell.h

//
//   Cell.h
//   Projects


#import <UIKit/UIKit.h>

@interface Cell : UITableViewCell


@property (weak, nonatomic) IBOutlet UIButton *btnCall;

@end

细胞.m

//
//  Cell.m


#import "Cell.h"


@implementation NearByDealDetailCell

- (void)awakeFromNib 
    [super awakeFromNib];




- (void)setSelected:(BOOL)selected animated:(BOOL)animated 
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state


@end

// ControllerVC.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

        static NSString *simpleTableIdentifier = @"Cell";
        Cell *cell = (Cell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
        if (cell == nil)
        
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"Cell" owner:self options:nil];
            cell = [nib objectAtIndex:0];
        


               cell.btnCall.tag =  indexPath.row;
        [cell.btnCall addTarget:self action:@selector(actionBtnCall:) forControlEvents:UIControlEventTouchUpInside];

        return cell;





- (IBAction)actionBtnCall:(id)sender 

    UIButton *btn = (UIButton *)sender;
    NearByDealModel *activity = (NearByDealModel *)[self.activityList objectAtIndex:[btn tag]];


【讨论】:

以上是关于在单元格中单击时,tableView:indexPathForCell 返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

单击单元格文本时如何从单元格中删除文本

在单元格中单击 UITextField 时,DidSelectRowAtIndexPath 的 indexPath 为零

如何在单击按钮时将 ImageView 添加到表格单元格中?

单击单元格本身而不是按钮时,(静态)单元格中的按钮会消失

如何在单击按钮时获取表格视图单元格中文本字段的值?

当我在 swift 中单击单元格中的文本字段时,键盘没有出现