UITableviewcontroller 中的 UITableview - 重新加载时未调用 cellforrowatindexpath
Posted
技术标签:
【中文标题】UITableviewcontroller 中的 UITableview - 重新加载时未调用 cellforrowatindexpath【英文标题】:UITableview in UITableviewcontroller - cellforrowatindexpath not called on reload 【发布时间】:2013-07-10 14:01:37 【问题描述】:两天以来我陷入了一个愚蠢的问题。我有一个UITableViewController
推入Navigation Controller
。加载时,由于没有数据,所以空表可见:
但是当我从服务器接收数据并调用 [self.tableView reloadData]
时,numberOfRowsInSection
和 heightForRowAtIndexPath
都得到调用,除了 cellForRowAtIndexPath
并且我的控制器显示为没有表格:
我真的不明白为什么会这样。除了cellForRowAtIndexPath
,所有数据源方法都被调用。请有人指导我...谢谢..
ActLogController.h
@interface ActLogController : UITableViewController<ASIHTTPRequestDelegate,UITableViewDataSource,UITableViewDelegate>
@property(strong) NSMutableArray *activityKeys;
@end
ActLogController.m
- (void)viewDidLoad
[super viewDidLoad];
activityKeys = [[NSMutableArray alloc] init];
self.tableView.dataSource = self;
-(void) viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];
[self retrieveActivityLogFromServer];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return activityKeys.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// Configure the cell...
ActivityLogUnit *act = [activityKeys objectAtIndex:indexPath.row];
cell.textLabel.text = act.price;
return cell;
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
return 50.0;
-(void) requestFinished:(ASIHTTPRequest *)request
NSArray *list = [request.responseString JSONValue];
for (int i = 0; i < list.count; i++)
NSArray *singleTrade = [[list objectAtIndex:i] JSONValue];
ActivityLogUnit *unit = [[ActivityLogUnit alloc] init];
unit.symbol = [singleTrade objectAtIndex:0];
unit.type = [singleTrade objectAtIndex:1];
unit.price = [singleTrade objectAtIndex:2];
unit.volTraded = [singleTrade objectAtIndex:3];
unit.remVol = [singleTrade objectAtIndex:4];
unit.actualVol = [singleTrade objectAtIndex:5];
unit.recordID = [singleTrade objectAtIndex:6];
unit.orderNo = [singleTrade objectAtIndex:7];
unit.time = [singleTrade objectAtIndex:8];
[activityKeys addObject:unit];
if(activityKeys.count > 0)
[self.tableView reloadData];//it is called and I have got 6 items confirm
编辑
我在数组activityKeys
中设置了一些虚拟数据,数据正在表格中显示,cellforrowatindexpath
调用成功。但是当我在某个时间后重新加载数据时,除了这个之外,其他方法都被调用了,并且表格消失了,如第二张图片所示。有什么想法吗?
【问题讨论】:
你连接IBOutlet for tableView了吗? 在 numberOfRowsInSection 中记录 activityKeys.count 以查看它返回的内容。 @Bhargavi 我的 tableviewcontroller 没有 xib 文件。 @rdelmar 它返回 6。令人惊讶的是,heightForRowAtIndexPath
被调用了 6 次,但 cellforrow.. 零次。
这很令人费解——我想不出任何理由只要 numberOfRowsInSection 返回大于 0 的数字就不会调用 cellForRowAtIndexPAth。你能把你的项目发布到某个地方吗?
【参考方案1】:
您的问题是您可能在后台线程上下载数据内容。由于您无法在后台更新 UI,因此您需要在下载完成后在主线程上调用 [self.tableView reloadData]!
希望对你有帮助!
【讨论】:
您的回答对我有帮助!我的解决方法是使用 performSelectorOnMainThread 重新加载数据。【参考方案2】:看起来你在辅助线程中,使用以下代码在主线程中执行 reloadData
[self.tableView performSelectorOnMainThread@selector(reloadData) withObject:nil waitUntilDone:NO]
您可以随时使用 [NSThread isMainThread] 来检查您是否在主线程中。
【讨论】:
感谢您的回答。它不工作。我仍然得到空白的白色视图:( 作为健全性检查,您确定 cellForRowAtIndexPath 没有被调用吗?断点.. NSLog.. 是的,我都使用过,并检查过它没有被调用。 您可以将 reloadData 调用替换为 [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5]; //延迟以避免多线程问题【参考方案3】:你必须在viewdidload中写
self.tableView.dataSource = self;
self.tableView.delegate = self;
编辑
你没有 xib,那么你在哪里声明/设置你的 tableview 的属性。喜欢
self.tableView.frame = CGRectMake(0, 45, 320, 500);
self.tableView.rowHeight = 34.0f;
self.tableView.separatorStyle=UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.tableView];
[self.tableView setBackgroundColor:[UIColor clearColor]];
self.tableView.showsVerticalScrollIndicator=NO;
self.tableView.dataSource = self;
self.tableView.delegate = self;
试试
@property(nonatomic,strong) NSMutableArray *activityKeys;
【讨论】:
我没有 xib,但仍然显示了最初的表格(第一张图片),并且还为其分配了参考。我也试过你的答案,但它没有帮助我:( 当你重新加载tableview的时候调用numberOfRowsInSection方法?或不?如果调用然后打印它计数。 是的,它被调用了。重新加载后计数为 6。【参考方案4】:首先我坚信tableview的实例名不应该与局部变量相似(即class中的tableView不应该等于delegate和data source方法中的tableView)。
在您发布的第二个问题中,我看不到为表格视图设置的委托。 如果您在 .h 或 .m 文件中设置了表视图的 @property,则由 Samir Rathod 发布的答案应该可以工作。
如果您有 XIB 文件,您也可以这样做。 按 ctrl 并单击 + 将 tableview 拖动到文件所有者并设置委托和数据源。
【讨论】:
首先,我没有任何实例。其次,我尝试使用 xib 并设置插座,但结果仍然相同.. 你记录了数组的计数吗???我知道你在上面提到过。但如果是这样的话,任何大于 0 的计数都应该调用 cellForRowAtIndex。可能有一个非常小的步骤,你必须错过。尝试再次诊断您的步骤。【参考方案5】:对我来说,问题是我的 stubbed-out 代码返回 0 作为节数(因此它从未询问该节中有多少行,也从未得到它们的数据)。如果这也是您的问题,只需将其更改为 1。此外,我在 Swift 中工作,@shahid-rasheed 提到的问题的编码(略有)不同:
dispatch_async(dispatch_get_main_queue(),
self.tableView.reloadData()
)
【讨论】:
【参考方案6】:我终于成功了。 cellForRowAtIndexPath
没有被调用,因为我在这里没有提到的一行代码......实际上是从视图中删除了一些颜色背景层。它导致重新加载问题。删除后一切正常。
感谢大家的合作:)
【讨论】:
【参考方案7】:我也有同样的症状。就我而言,我第一次在 viewDidLoad 中加载数据(来自核心数据)时,NSSortDescriptor 用于对数据进行排序。
点击一个按钮,核心数据被再次获取(这次有变化)并重新加载了 tableView 数据。它最初在单击按钮后给了我一个空白表格视图,因为我第二次获取它时忘记对数据进行排序。
学习要点:如果你一开始就使用过,记得调用所有修改单元格的方法(比如 iAnum 提到的背景颜色,或者我的例子中的 NSSortDescriptor)!
【讨论】:
以上是关于UITableviewcontroller 中的 UITableview - 重新加载时未调用 cellforrowatindexpath的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewController 中的 iOS tableHeaderView 从不显示
框架中的 UITableViewController 未调用 didSelectRowAtIndexPath