Данные не загружаются в UITableView, пока я не прокручиваю


Я пытаюсь загрузить проанализированные данные в ячейки, но проблема в том, что это происходит синхронно и UitableView не показывает, пока данные не закончат загрузку. Я попытался решить проблему с помощью performSelectorInBackground, но теперь данные не загружаются в ячейки, пока я не начну прокрутку. Вот мой код:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self performSelectorInBackground:@selector(fethchData) withObject:nil];


}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
self.listData = nil;
    self.plot=nil;
}


-(void) fethchData

{
    NSError *error = nil;
    NSURL *url=[[NSURL alloc] initWithString:@"http://www.website.com/"];
    NSString *strin=[[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

    HTMLParser *parser = [[HTMLParser alloc] initWithString:strin error:&error];

    if (error) {
        NSLog(@"Error: %@", error);
        return;
    }

    listData =[[NSMutableArray alloc] init];
    plot=[[NSMutableArray alloc] init];

    HTMLNode *bodyNode = [parser body];
    NSArray *contentNodes = [bodyNode findChildTags:@"p"];


    for (HTMLNode *inputNode in contentNodes) {
            [plot addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];    
        }


    NSArray *divNodes = [bodyNode findChildTags:@"h2"];

    for (HTMLNode *inputNode in divNodes) {

            [listData addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];          

        }
    }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

    static NSString *CellIdentifier = @"Cell";
    //here you check for PreCreated cell.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }

    //Fill the cells...  


    cell.textLabel.text = [listData objectAtIndex:indexPath.row];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
    cell.textLabel.numberOfLines=6; 
    cell.textLabel.textColor=[UIColor colorWithHue:0.7 saturation:1 brightness:0.4 alpha:1];


    cell.detailTextLabel.text=[plot objectAtIndex:indexPath.row];
    cell.detailTextLabel.font=[UIFont systemFontOfSize:11];
    cell.detailTextLabel.numberOfLines=6;

    return cell;


}
7 52

7 ответов:

положите это куда-нибудь после успешной загрузки данных:

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

это устранить проблему вызова графического интерфейса пользователя обновление пока ты не в главном потоке.

этот код использует технологию GCD от Apple, чтобы заставить функцию перезагрузки данных работать в основном потоке. Подробнее о Руководство По Программированию Параллелизма для большего понимания (это довольно большое поле, так что его трудно объяснить в комментарии) Во всяком случае, это не очень рекомендуется, если вы не понимаете это хорошо, потому что это приводит к сбою программы в некоторых редких случаях.

для swift 3:

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

для swift 2:

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

все, что вам действительно нужно сделать это в любое время обновить ваши данные, звоните

[tableView reloadData];

Так как это происходит синхронно, вы, вероятно, должны иметь функцию, как

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

и после добавления данных в скачать Call

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

U может использовать [cell setNeedsDisplay]; например:

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

У меня была точно такая же проблема! Я хотел, чтобы UITableView был полностью заполнен до появления контроллера вида. Сообщение энвила дало мне необходимую информацию, но мое решение оказалось другим.

вот что я сделал (переделан, чтобы соответствовать контексту вопроса asker).

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

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

У меня была эта проблема, и я занимался этим весь день.

Я использую статические ячейки, а reloadData вызывает неправильную загрузку, он отображает только видимые ячейки и удаляет другие. Я заметил, что когда я прокрутил вниз (y отрицательное значение) ячейки, где правильно, поэтому я написал этот код, и он работал, хотя я не хочу в эту сторону.

стрелять, если вы найдете лучшее решение.

-(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) {

            }];
        }];
}

во-первых, это полу-решена моя проблема. Я хочу закруглить углы изображения в ячейку таблицы. Асинхронная отправка исправила проблему для некоторых, но не для всех изображений. Есть идеи?

во-вторых, я думаю, что вы должны избегать создания сильного ссылочного цикла, используя список захвата закрытия следующим образом:

DispatchQueue.main.async(execute: { [weak weakSelf = self] () -> Void in
            weakSelf!.tableView.reloadData()
        })

посмотреть: https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID52