Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data doesn't load in UITableView until I scroll

Put this somewhere after the data is loaded successfully:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});

This fix the problem of calling a GUI update while you're not in the main thread.

This code uses the GCD Technology from Apple to force the reload data function to run on main thread. Read more about Concurrency Programming Guide for more understanding (it's quite large field so that it's hard to explain in the comment) Anyway, it's not very recommended if you don't understand it well because it causes the program to crash some rare cases.


For swift 3:

DispatchQueue.main.async(execute: { () -> Void in
                self.tableView.reloadData()
            })

For swift 2:

dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
            })

All you really need to do is any time you have an update to your back-end data, call

[tableView reloadData];

Since this is happening synchronously, you should probably have a function like

-(void) updateTable
{
    [tableView reloadData];
}

and after adding the data in your download call

[self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:NO];

U can use [cell setNeedsDisplay]; for example:

dispatch_async(dispatch_get_main_queue(), ^{
            [cell setNeedsDisplay];
            [cell.contentView addSubview:yourView];
        });

I had this problem and I was dealing with it all the day.

I am using static cells and reloadData is causing the wrong loading, it displays only the visible cells and remove the others. What I noticed is that when I scrolled down (y in negative value) the cells where loaded correctly, so I wrote this code and it worked, even though I don't like to let it in this way.

Shoot if you find any better solution.

-(void)reloadTableView{
        CGPoint point = self.tableSettings.tableView.contentOffset;
        [self.tableSettings.tableView reloadData];

        [UIView animateWithDuration:.001f animations:^{
            [self.tableSettings.tableView setContentOffset:CGPointMake(point.x, -10)];
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:.001f animations:^{
                [self.tableSettings.tableView setContentOffset:point];
            } completion:^(BOOL finished) {

            }];
        }];
}

I was having the exact same problem! I wanted the UITableView to be fully populated before the view controller appeared. Envil's post gave me the information I needed, but my solution ended up being different.

Here's what I did (remodeled to fit the context of the question asker).

- (void)viewDidLoad {
    [super viewDidLoad];
    [self performSelectorInBackground:@selector(fethchData) withObject:nil];
}

- (void)viewWillAppear {
    [tableView reloadData];
}