TableView reloadData не работает
Когда я вызываю [tableView reloadData]
, функция - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
не запускается? Почему?
Здесь мой TableView.m
@implementation TableView
@synthesize managedObjectContext;
@synthesize controller = _controller;
@synthesize tableView = _tableView;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
-(id)init
{
self = [super init];
if (self) {
NSLog(@"%s",__PRETTY_FUNCTION__);
self.del = [[UIApplication sharedApplication] delegate];
self.managedObjectContext = self.del.managedObjectContext;
[self performControllerFetch];
}
return self;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
...
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
...
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
...
}
-(void)reloadTableView
{
NSLog(@"%s",__PRETTY_FUNCTION__);
[self.tableView reloadData];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(@"%s",__PRETTY_FUNCTION__);
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
@end
TableView.h
@interface TableView : UITableView <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate>
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) AppDelegate *del;
@property (nonatomic, strong) NSFetchedResultsController *controller;
@property (weak, nonatomic) IBOutlet TableView *tableView;
-(void)reloadTableView;
-(void)performControllerFetch;
@end
Ответы
Ответ 1
Похоже, вы никогда не устанавливаете свойства delegate
и datasource
в своем представлении таблицы, нет? Вы реализуете методы в тех протоколах внутри tableview.m
, но не устанавливаете два свойства в self
, поэтому вызов reloadData
не имеет эффекта.
Помогает ли это?
Edit:
Похоже, у вас есть свойство tableView
, заданное в подклассе UITableView
, и подключено к файлу построителя интерфейса. Это нечетная настройка (tableview в виде таблицы). Обычно у вас есть что-то вроде подкласса UIViewController
, подключенного к XIB и устанавливающего
@property (nonatomic, strong) IBOutlet UITableView * tableView
в этом подклассе или что-то подобное. Затем обработайте выборку данных и делегат/источник данных таблицы в этом подклассе viewcontroller.
Но здесь, из-за вложенного UITableView
, это не так просто. Есть ли причина для этого дизайна? Я рекомендую перейти к чему-то подобному, описанному выше, чтобы внести ясность в настройку.
Кроме того, попробуйте добавить несколько операторов NSLog
в свой метод init
, чтобы узнать, установлены ли свойства tableview!= nil, а также свойства делегата и datasource. Мое подозрение в том, что соединение не выполняется.
Кроме того, не связанный с проблемой, вам больше не нужно вручную @synthesize ivar = _ivar
, это будет сделано для вас автоматически, используя соглашение подчёркивания.
Ответ 2
У меня была такая же проблема, что перезагрузка не работала. Я полагаю, что метод делегата, который я вызывал из него, был в фоновом потоке, который вызывал проблему. Моим решением было создать новый метод (см. Ниже) и вместо этого вызвать перезагрузить, а также обеспечить его вызов из основного потока
- (void) tocLoad {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
Ответ 3
Если вы не можете перезагрузить таблицу, используя
[self.tableView reloadData];
Пожалуйста, убедитесь, что вы добавили ссылку на следующую раскладку
@property (weak, nonatomic) IBOutlet TableView *tableView;
Как добавить ссылку, вы можете нажать следующую ссылку:
таблица сравнения tableView
Ответ 4
Несмотря на то, что вы пишете эту кнопку [self.tableView reloadData];
, попробуйте ниже, потому что вы уже написали класс, поэтому не нужно снова принимать розетки: -
[self reloadData]
Ответ 5
Я потратил несколько дней на отладку этой проблемы и нашел массу возможных исправлений. Я снялся в одном фильме, который работал у меня, но все они действительны.
Сначала, конечно, убедитесь, что ваш делегат, источник данных, IBOutlet и т.д. настроены правильно.
** Установите контрольную точку All Exceptions и проверьте, не возникает ли исключение из-за пределов в вашем источнике данных. Без установки точки останова нет сбоя, и табличное представление просто не перезагрузится.
Другие возможные исправления: проверьте рамку tableview, чтобы убедиться, что ширина или высота не равны 0. Попробуйте выполнить reloadData в основном потоке. Наконец, попробуйте только перезагрузить один раздел (здесь).
Нужно просматривать таблицы в таблице.
Ответ 6
Это случилось со мной, потому что был звонок
tableView.beginUpdates()
без звонка
tableView.endUpdates()
В моем коде. Удаление tableView.beginUpdates()
решило проблему для меня.