cellForRowAtIndexPath: не вызывается reloaddata

Я знаю, что это проблема с запятой, но cellForRowAtIndexPath: не вызывается, когда я использую [actionTableView reloadData];. Я уже связал dataSource и delegate благодаря раскадровке, но это не решает проблему.

Вот часть моего кода:

SearchViewController.h

#import <UIKit/UIKit.h>

@interface SearchViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchDisplayDelegate>

@property (strong, nonatomic) IBOutlet UITableView *actionTableView;
@property (strong, nonatomic) IBOutlet UISearchBar *actionSearchBar;
@property (strong, nonatomic) NSMutableArray *actionsArray;
@property (strong, nonatomic) NSMutableArray *filteredActionArray;

@end

SearchViewController.m

#import "SearchViewController.h"
#import "Action.h"

@interface SearchViewController ()

@end

@implementation SearchViewController

@synthesize actionsArray, actionTableView, filteredActionArray, actionSearchBar;

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return [filteredActionArray count];
    } else {
        return [actionsArray count];
    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if ( cell == nil ) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    NSLog(@"Aloha");

    // Create a new Action object
    Action *a = nil;

    if (tableView == self.searchDisplayController.searchResultsTableView) {
        a = [filteredActionArray objectAtIndex:indexPath.row];
    } else {
        a = [actionsArray objectAtIndex:indexPath.row];
    }

    // Configure the cell
    cell.textLabel.text = a.nomAction;
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
    return cell;
}

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
    // Update the filtered array based on the search text and scope.
    // Remove all objects from the filtered search array
    [self.filteredActionArray removeAllObjects];
    // Filter the array using NSPredicate
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.nomAction contains[c] %@",searchText];
    filteredActionArray = [NSMutableArray arrayWithArray:[actionsArray filteredArrayUsingPredicate:predicate]];
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
    // Tells the table data source to reload when text changes
    [self filterContentForSearchText:searchString scope:
     [[self.searchDisplayController.searchBar scopeButtonTitles]objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
    // Tells the table data source to reload when scope bar selection changes
    [self filterContentForSearchText:self.searchDisplayController.searchBar.text scope:
     [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
    // Return YES to cause the search result table view to be reloaded.
    return YES;
}

Как видите, я также использую searchBar для фильтрации массива, но без этого он тоже не работает.

EDIT: СПЕЦИФИКАЦИЯ ПРОБЛЕМЫ: reloadData работает только в том случае, если я вызываю его в viewController. Нет, если я вызову его из другого viewController. Очевидно, что в обоих случаях я вызываю одну и ту же функцию updatingTableView, расположенную в контроллере представления, где находится tableView. Есть идеи перезагрузить tableView из другого ViewController?

SearchViewController.m (работает)

-(IBAction)update{
    [self updatingTableView:nil];
}

-(void)updatingTableView:(NSData*)someData {
   actionsArray = [NSArray arrayWithObjects:@"item1", @"item2", @"item3", nil];
   [actionTableView reloadData];
}

AnotherViewController.m (не работает)

-(IBAction)updateFromElsewhere{
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main"
                                                         bundle: nil];

    SearchViewController *searchViewController = (SearchViewController*)    [mainStoryboard
                                                             instantiateViewControllerWithIdentifier: @"searchcontroller_id"];

    [searchViewController updatingTableView:nil];

}

NB: я могу без проблем передать некоторые данные из контроллера представления в другой.


person romain64    schedule 19.07.2015    source источник
comment
Убедитесь, что ваши tableView: numberOfRowsInSection не возвращают 0   -  person teamnorge    schedule 19.07.2015
comment
numberOfSectionsInTableView и numberOfRowsInSection даже не называются   -  person romain64    schedule 19.07.2015
comment
тогда ваш контроллер представления не слушает UITableViewDelegate, я не уверен, как вы соединили их в раскадровке. Но если вы на 100% уверены, что все сделали правильно, и если это подходит для вашего проекта, вы можете реализовать метод awakeFromNib, где вы поместите actionTableView.delegate = self   -  person teamnorge    schedule 19.07.2015
comment
Да все хорошо подключено. С awakeFromNib тоже не работает. numberOfSectionsInTableView и numberOfRowsInSection вызываются только один раз при открытии приложения, но в этот момент массив пуст. Затем, когда я использую IBAction для загрузки данных в NSArray, а затем обрабатываю reloadData, они больше не вызываются.   -  person romain64    schedule 19.07.2015
comment
для принудительного вызова numberOfRowsInSectionare и numberOfSectionsInTableView можно положить свои reload data внутрь [tableView beginUpdates]; [tableView reloadData]; [tableView endUpdates]; в общем не обязательно если не удалять/вставлять ячейки, а просто как обходной путь чтобы понять что не так.   -  person teamnorge    schedule 19.07.2015
comment
также проверьте, правильно ли подключен ваш источник данных к владельцу файла. И если даже это не поможет, я бы предложил удалить tableView из вашей раскадровки, добавить новый и начать делать все с нуля.   -  person teamnorge    schedule 19.07.2015
comment
Это ничего не меняет с beginUpdates и endUpdates. Да, я начну все с нуля. У меня есть другой проект с точно таким же кодом и где он работает, это странно.   -  person romain64    schedule 19.07.2015


Ответы (3)


Одна вещь, с которой я всегда сталкиваюсь, когда пытаюсь создать табличное представление, — это соединение таблицы с интерфейсом с помощью построителя интерфейса. Но когда вы вызываете [actionTableView reloadData] без подключения к таблице, ничего не произойдет.

Я могу забыть этот супер простой шаг. Надеюсь, это помогло

person ErickES7    schedule 19.07.2015
comment
Я проверял это не менее десяти раз! Розетка actionTableView, delegate и dataSource подключены к IB. - person romain64; 19.07.2015
comment
Дэн! Хорошо, и вы знаете, что методы не вызываются, потому что у вас есть точка останова? Откуда ты знаешь, что не звонят??? - person ErickES7; 19.07.2015
comment
Хорошо, ммм, попробуйте назначить делегата и источник данных автоматически, как в viewDidAppear: затем вызовите reloadData в коде сразу после этого, если что-то пошло не так в раскадровке. - person ErickES7; 19.07.2015
comment
Это не работает программно с actionTableView.delegate = self и actionTableView.dataSource = self. Я действительно не знаю, что случилось - person romain64; 19.07.2015
comment
Я ничего не получил. Я кратко просмотрел эту ссылку, но не вижу большой разницы, потому что я работаю только с xib, а не с раскадровками. Может быть, ответом будет недостающий шаг?? appcoda.com/uitableview-tutorial-storyboard-xcode5 - person ErickES7; 19.07.2015
comment
Инициализация работает, но я все еще не могу обновить ее с помощью reloadData - person romain64; 20.07.2015

Проблема в том, что вы никогда не инициализируете actionsArray и filteredActionArray ненулевыми. В результате numberOfRowsInSection всегда возвращает 0, поэтому cellForRowAtIndexPath вызываться не будет.

person Dklionsk    schedule 19.07.2015
comment
Перед вызовом reloadData functionsArray загружается другая функция, здесь не показанная. И перед перезагрузкой данных проверяю содержимое NSArray и все ок - person romain64; 19.07.2015
comment
Это очень странно, поэтому numberOfSectionsInTableView: никогда не вызывается? Вы поставили точку останова на заголовок функции и ничего? Поскольку любое табличное представление, источник данных которого прикреплен к чему-либо, будет автоматически загружать свои данные при загрузке представления, оно должно вызывать эти функции хотя бы один раз. - person ErickES7; 20.07.2015

Наконец нашел решение!

В SearchViewController.m, где находится tableView, поместите это в viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatingTableView) name:@"reload_data" object:nil];

С еще:

-(void)updatingTableView{
    [actionTableView reloadData];
}

В AnotherViewController.m

[[NSNotificationCenter defaultCenter] postNotificationName:@"reload_data" object:self];

как перезагрузить табличное представление другого uiviewcontroller в текущем контроллере представления

Спасибо всем!

person romain64    schedule 19.07.2015
comment
Так что вам пришлось удалить уведомление?? - person ErickES7; 20.07.2015