2014-10-21 2 views
4

я заметил несколько вопросов, похожих на этот на SO, но все они, кажется, до конца в лице звалиИОС: UITableView reloadData не работает, пока свиток

[self.tableView reloadData] 

за пределы основного потока.

Моя проблема заключается в том, что я называю это в основном потоке пользовательского интерфейса, и я до сих пор не загружаю новые строки, пока мне не нравится использовать экран или немного прокручивать. Вот что я делаю: когда я вхожу в свой ViewController, таблица отображается полностью и правильно. После нажатия кнопки на представлении я вызываю свой внешний db и загружаю некоторые новые строки, которые нужно добавить в таблицу. После добавления их в свой источник данных я вызываю 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 называется в главном потоке. Но я решил, что просто попробую.

Я не вижу причин, почему это не работает.

+0

ли вы проверить в момент, когда вы звоните '' reloadData' что self.tableView' не 'nil'? Вы проверили, что 'tableView: numberOfRowsInSection:' возвращает правильный счетчик (т. Е. Не ноль)? Вы подтвердили свой источник данных (я предполагаю, что 'self.locations'?) Содержит данные? Вы подтвердили правильность 'self.tableView.frame', и он фактически находится в текущем' UIWindow' (например, 'self.tableView.superview' не' nil')? –

+0

self.tableView не nil, numberOfRowsInSection возвращает правильную сумму - это было 20, теперь это 40, self.locations содержит 40 объектов, все из которых являются тем, что я ожидаю от них, и self.tableView.superview определенно не UIWindow, это то, что должно быть. – user1513171

+0

Что, по-видимому, вызывает проблему после вызова realoadData, cellForIndexPath не вызывается для каких-либо из этих новых ячеек, которые я добавил, хотя хотя бы один или два из них должны быть, потому что их нет в представлении. – user1513171

ответ

0

правильный путь:

[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]; 
Смежные вопросы