ios:UITableView reloadData在滚动之前无法正常工作

时间:2014-10-21 00:44:08

标签: ios uitableview reloaddata ui-thread

我已经注意到了一些类似于这个问题的问题,但他们似乎都在这个人的呼唤中结束了

 [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。但我想我还是会尝试一下。

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

1 个答案:

答案 0 :(得分: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];