Данные не загружаются в 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 ответов:
положите это куда-нибудь после успешной загрузки данных:
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() })