Question

I am calling a method in my TableViewController class from another class.

To call the method of displaying the tableview, I do this:

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

then in 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;
}

For some reason when I try to log the tableview, it returns null, so the ReloadData doesn't work. The delegate and datasource is connected properly in IB, and there is a referencing outlet for tableView.

Any idea what is going on here? Thanks in advance

Was it helpful?

Solution

If you added the table view controller to a container view, then you can get a reference to that controller in prepareForSegue. For a controller in a container view, prepareForSegue will be called right before the parent controller's viewDidLoad, so you don't need to do anything to invoke it. In my example below, I've called the segue "TableEmbed" -- you need to give the segue that identifier in IB.

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

Be aware that prepareForSegue:sender: is called before either controller's viewDidLoad is called, so you should move the initialization of your array to setTableViewContent, and your reloadTable should go into viewDidLoad.

BTW, it's not clear to me why you want to call setTableContent from your other class anyway. Why not move all the code in that method to the viewDidLoad method of the table view controller?

OTHER TIPS

This is happening because you are calling a method on tableView before it actually exists. Simply initializing that class doesn't draw the table itself, so using reloadData before the table has actually been created doesn't really make any sense.

What you want to do in this situation is create your nameArray in whatever class is calling setTableViewContent, and then pass it in either via a custom init method, or by setting tableVC.nameArray before loading that table view controller.

What I would do is make custom init method like - (id)initWithArray:(NSMutableArray *)nameArr

Which should look something like this:

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

Then where you have TableViewController *tableVC = [[TableViewController alloc]init]; put TableViewController *tableVC = [[TableViewController alloc]initWithArray:theNameArray]; where theNameArray is the content in setTableViewContent (which you are now generating in the same class that calls the table view instead of in the table view itself).

Make sense?

I solved a similar situation by creating a "safe" reload method on the UITableViewController:

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

According to the docs for isViewLoaded:

Calling this method reports whether the view is loaded. Unlike the view property, it does not attempt to load the view if it is not already in memory.

Therefore it is safe to call reloadTableViewData on the table view controller at any time.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top