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] 时,numberOfRowsInSectionheightForRowAtIndexPath 都得到调用,除了 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 中的 iAd

UITableViewController 中的 iOS tableHeaderView 从不显示

UITableViewController 中的顶栏背景

框架中的 UITableViewController 未调用 didSelectRowAtIndexPath

从 UITableViewController 中的按钮创建操作

在 UITableViewController 中的 UITableViewCells 之间进行通信