ios:UITableView reloadData 在滚动之前不起作用

Posted

技术标签:

【中文标题】ios:UITableView reloadData 在滚动之前不起作用【英文标题】:ios: UITableView reloadData not working until scroll 【发布时间】:2014-10-21 00:44:08 【问题描述】:

我注意到一些与 SO 类似的问题,但它们似乎都以打电话的人结束

 [self.tableView reloadData]

在主线程之外。

我的问题是,我在主 UI 线程上调用它,但我仍然没有加载新行,直到我喜欢点击屏幕或滚动一点。这就是我正在做的事情:当我输入 ViewController 时,表格会完全正确地显示。在视图上按下按钮后,我调用我的外部数据库并加载一些新行以添加到表中。将这些添加到我的数据源后,我调用 reloadData 并且所有新行都是空白的。仍然适合屏幕的几行已经是表格的一部分仍然显示,但没有什么新内容。当我触摸屏幕或滚动一点点时,所有新单元格都会弹出。

这是我对服务器的调用完成后开始的代码:

     - (void)connectionDidFinishLoading:(NSURLConnection *)connection 

if(connection == self.searchConnection) 

 ..... some code ......

    if(successful) 
        // Adding new data to the datasource
        [self.locations removeObjectAtIndex:[[NSNumber numberWithInt:self.locations.count - 1] integerValue]];
            [self.cellTypeDictionary removeAllObjects];
            for(int i = 0; i < [jsonLocations count]; ++i) 
                NSDictionary *locationDictionary = jsonLocations[i];
                BTRLocation *location = [BTRLocation parseLocationJSONObject:locationDictionary];
                [self.locations addObject:location];
            


        if(self.currentNextPageToken != nil && ![self.currentNextPageToken isEqual:[NSNull null]] && self.currentNextPageToken.length > 0) 
            BTRLocation *fakeLocation = [[BTRLocation alloc] init];
            [self.locations addObject:fakeLocation];
        

        [self determineCellTypes];
        if([self.locations count] < 1) 
            self.emptyView.hidden = NO;
         else 
            ... some code .....

            if(self.pendingSearchIsNextPageToken) 
                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[[NSNumber numberWithInt:countBefore] integerValue]

                                                            inSection:[[NSNumber numberWithInt:0] integerValue]];

                dispatch_async(dispatch_get_main_queue(), ^
                    [self.tableView reloadData];
                    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
                );
             else 
                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[[NSNumber numberWithInt:0] integerValue]
                                                            inSection:[[NSNumber numberWithInt:0] integerValue]];

                dispatch_async(dispatch_get_main_queue(), ^
                    [self.tableView reloadData];
                    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
                );
            
        
     else 
        if(invalidAccessToken) 
            // TODO: invalidAccessToken need to log out
        
    

你可以看到我什至添加了

  dispatch_async(dispatch_get_main_queue(), ^
                    [self.tableView reloadData];
                    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
                );

即使我知道在主线程上调用了 connectionDidFinishLoading。但我想我还是试试吧。

我看不出这不起作用的原因。

【问题讨论】:

您是否在调用reloadData 时确认self.tableView 不是nil?您是否验证 tableView:numberOfRowsInSection: 返回正确的计数(即不为零)?您是否验证了您的数据源(我假设 self.locations?)包含数据?你确认self.tableView.frame是正确的,它实际上是在当前的UIWindow(例如self.tableView.superview不是nil)? self.tableView 不是 nil,numberOfRowsInSection 返回正确的数量 - 它是 20 现在是 40,self.locations 包含 40 个对象,所有这些都是我期望的,还有 self.tableView。 superview 绝对不是 UIWindow,它应该是。 似乎导致问题的原因是在调用 realoadData 之后,我添加的任何这些新单元格都没有调用 cellForIndexPath,即使其中至少有一个或两个应该是因为它们不在视图。 【参考方案1】:

正确的做法是:

[self.tableView reloadData];
__weak MyViewController* weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^
                 __strong MyViewController *strongSelf = weakSelf;
                [strongSelf.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
            );

有时我发现你在reloadData之后添加:

[self.tableView layoutIfNeeded];

【讨论】:

以上是关于ios:UITableView reloadData 在滚动之前不起作用的主要内容,如果未能解决你的问题,请参考以下文章

iOS小技能:1. 什么是UITableView? 2. UITableView如何展示数据

iOS开发之UITableView的使用

iOS开发UI篇—UITableview控件简单介绍

iOS横竖滚动UITableView

iOS-UITableView重用机制

iOS基础——通过案例学知识之UITableView(上)