2013-07-17 2 views
3

Я вызываю метод в классе TableViewController из другого класса.ReloadData для UITableView не работает; tableView возвращает NULL при регистрации

Для вызова метода отображения TableView, я делаю это:

TableViewController *tableVC = [[TableViewController alloc]init]; 
[tableVC setTableViewContent]; 

затем в TableViewController.h

@interface TableViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> 
{ 
NSMutableArray *nameArray; 
} 

-(void)setTableViewContent; 
@property (nonatomic, strong) IBOutlet UITableView *tableView; 

@end 

TableViewController.m

@implementation TableViewController 
@synthesize tableView; 


- (void)viewDidLoad 
{ 
nameArray = [[NSMutableArray alloc]init]; 
[super viewDidLoad]; 

} 

-(void)setTableViewContent{ 


AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 

for(int i=0;i< [appDelegate.businessArray count];i++) 
{ 

    NSDictionary *businessDict = [[appDelegate.businessArray objectAtIndex:i] valueForKey:@"location"]; 


    nameArray = [appDelegate.businessArray valueForKey:@"name"]; 

} 
NSLog(@"%@", nameArray); 


    NSLog(@"tableview: %@", tableView); 

// here tableview returns null 
[tableView reloadData]; 


} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 

// Return the number of sections. 
return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

// Return the number of rows in the section. 
return [nameArray count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"updating tableview..."); 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    // Configure the cell... 
     cell.textLabel.text = [nameArray objectAtIndex:indexPath.row]; 

    return cell; 
} 

По какой-то причине, когда Я пытаюсь log tableview, он возвращает null, поэтому ReloadData не работает. Делегат и источник данных правильно подключены к IB, и для tableView имеется реферирующий выход.

Любая идея, что здесь происходит? Заранее спасибо

+0

Вы пробовали его после '[tableView reloadData]'? –

+0

@AhmedZ. да, по-прежнему возвращает NULL – Spenciefy

+0

Вам нужно проверить, есть ли '- (id) initWithStyle: (UITableViewStyle) style { self = [super initWithStyle: style]; if (self) { } return self; } 'существует в вашем классе или нет. –

ответ

3

Если вы добавили контроллер табличного представления в вид контейнера, вы можете получить ссылку на этот контроллер в файле prepareForSegue. Для контроллера в представлении контейнера prepareForSegue будет вызываться прямо перед viewDidLoad родительского контроллера, поэтому вам не нужно ничего делать, чтобы вызвать его. В моем примере ниже, я назвал segue «TableEmbed» - вам нужно дать segue этот идентификатор в IB.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if([segue.identifier isEqualToString:@"TableEmbed"]) { 
     TableViewController *tableVC = (TableViewController *)segue.destinationViewController; 
     [tableVC setTableViewContent]; 
    } 
} 

Имейте в виду, что prepareForSegue: Отправитель: вызывается перед viewDidLoad либо контроллера называется, так что вы должны переместить инициализацию вашего массива setTableViewContent, и ваш reloadTable должны идти в viewDidLoad.

Кстати, мне непонятно, почему вы все равно хотите вызвать setTableContent из своего другого класса. Почему бы не переместить весь код этого метода в метод viewDidLoad контроллера табличного представления?

+0

В основном я подключаюсь к серверу, чтобы сначала извлекать данные, поэтому, когда приложение загружается первым, нет ничего, чтобы заполнить таблицу. Из-за этого я должен получить все данные с сервера, а затем заполнить tableview, предположительно, на пустой таблице с reloadData. Вот почему мне нужно вызвать setTableContent, после того как я закончу вытаскивание данных с сервера. – Spenciefy

+0

И поскольку prepareForSegue: отправитель вызывается перед viewdidloads, нет данных, чтобы заполнить tableview, так как притяжение сервера еще не закончено (даже не началось). Прямо сейчас я могу заполнить tableview в viewdidload непосредственно в классе tableViewController с помощью локально хранимого массива, но мне нужно сначала вытащить массив с сервера, а THEN заполнить табличное представление. В этом случае я не думаю, что подготовкаforsegue будет работать. исправьте меня, если я ошибаюсь. – Spenciefy

+0

@Spenciefy, тогда вы должны создать свойство для своего TableViewController и установить его значение в prepareForSegue, как я сделал (он просто изменится на self.tableVC = * tableVC = (TableViewController *) segue.destinationViewController). Затем вызовите setTableContent на этом свойстве, когда вы закончите загрузку, а не в prepareForSegue. – rdelmar

0

Это происходит потому, что вы вызываете метод на tableView до его фактического существования. Просто инициализация этого класса не рисует сама таблица, поэтому использование reloadData до того, как таблица фактически была создана, на самом деле не имеет никакого смысла.

Что вы хотите сделать в этой ситуации: создайте свой имяArray в любом классе, вызывающем setTableViewContent, а затем передайте его либо с помощью специального метода инициализации, либо путем установки tableVC.nameArray перед загрузкой этого контроллера табличного представления.

Что бы я сделать, это метод пользовательских инициализации как - (id)initWithArray:(NSMutableArray *)nameArr

Который должен выглядеть примерно так:

if (self = [super init]) { 
    nameArray = [nameArr copy]; 
} 
return self; 

Тогда где вы TableViewController *tableVC = [[TableViewController alloc]init]; положил TableViewController *tableVC = [[TableViewController alloc]initWithArray:theNameArray]; где theNameArray является содержание в setTableViewContent (который вам теперь генерируются в том же классе, который вызывает представление таблицы, а не в самом представлении таблицы).

Имеют смысл?

+0

Я понимаю вашу логику, но когда я реализую ее в tableView, не совсем получается. Я называю инициализации с 'TableViewController * tableVC = [[TableViewController Alloc] initWithArray: NameArray];' , а затем в tableviewcontroller я поставил '- (ID) initWithArray: (NSMutableArray *) nameArr { если (само = [super init]) { nameArray = [имяArr copy]; } return self; } ' и nameArray возвращает штраф, но табличное представление не выполняется. – Spenciefy

+0

Кроме того, tableView существует, прежде чем я его назову. Пустой tableView является первым экраном в приложении, я могу заполнить его вручную. – Spenciefy

+0

Что произойдет, если вы запустите [tableView reloadData] в нижней части viewDidLoad? Возможно, что-то странное происходит там. Кроме того, поскольку вы устанавливаете nameArray в своем init сейчас, обязательно удалите 'nameArray = [[NSMutableArray alloc] init];' from viewDidLoad! – Stakenborg

0

я решил аналогичную ситуацию, создав «безопасный» метод перезагрузки на UITableViewController:

- (void)reloadTableViewData 
{ 
    if ([self isViewLoaded]) 
     [self.tableView reloadData]; 
} 

Согласно docs for isViewLoaded:

Вызов этого метода отчетов загружен ли вид. В отличие от свойства view, он не пытается загрузить представление, если он еще не находится в памяти.

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