Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewCell textLabel, does not update until a scroll, or touch happens, while using GCD

Can someone help me figure this out please?

My UITableViewCell textLabel, does not update until I scroll, or touch it.

The ViewController loads, it shows the right amount of cells. But the content is blank. I have to touch it or scroll to make my textLabel appear.

Am I doing something wrong here?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    [[cell textLabel] setFont: [UIFont systemFontOfSize: 32.0]];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSDictionary * data = [self timeForObject: [self.months objectAtIndex:indexPath.row]];

        dispatch_async(dispatch_get_main_queue(), ^{

            NSString *time      = [data objectForKey:@"Time"];
            NSString *totalTime = [data objectForKey:@"Total Time"];

            NSString * textLabel  = [NSString stringWithFormat:@" %@ %@",
                                        time, totalTime];

            [[cell textLabel] setText:textLabel];



        });
    });

    return cell;
}

Any help is appreciated

Thank you!

Nuno

EDIT:

A call to [cell setNeedsLayout] fixes this issue. Thank you everyone for your help!

like image 777
nmdias Avatar asked Aug 27 '12 09:08

nmdias


2 Answers

It seems that just setting the text of the cell is not enough for it to be refreshed. Have you tried putting [cell setNeedsDisplay] after setting the text and see what happens? BTW, since you are already using GCD to compute stuff in the background you should try to avoid doing any work at all on the main queue. I would write that piece of code more like:

NSDictionary *data = [self timeForObject: [self.months objectAtIndex:indexPath.row]];
NSString *time      = [data objectForKey:@"Time"];
NSString *totalTime = [data objectForKey:@"Total Time"];
NSString *textLabel = [NSString stringWithFormat:@" %@ %@", time, totalTime];

dispatch_async(dispatch_get_main_queue(), ^{
    [[cell textLabel] setText:textLabel];
    [cell setNeedsDisplay];
});
like image 131
Grzegorz Adam Hankiewicz Avatar answered Nov 10 '22 15:11

Grzegorz Adam Hankiewicz


You seem to be updating the cell on another thread (which is not the main thread)

Try this when you reload the tableview:

Objective-C

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

Swift

dispatch_async(dispatch_get_main_queue()) {
    self.tableView.reloadData()
}
like image 35
Nisarg Shah Avatar answered Nov 10 '22 15:11

Nisarg Shah