在单元格中单击时,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
,如果之前在同一运行循环迭代中发出 reloadData
或 reloadRowsAtIndexPaths: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 为零