Brett
Brett

Reputation: 1781

Initialize UITableView with dynamic data

I am trying to display a list of friends in a UITableView.

I am loading the friends:

- (void)viewDidLoad
{
  [super viewDidLoad];
  [self apiGraphFriends];
}

Then I am setting my results in:

- (void)request:(FBRequest *)request didLoad:(id)result 
{
friends = [[NSMutableArray alloc] initWithCapacity:1];
NSArray *resultData = [result objectForKey:@"data"];
if ([resultData count] > 0) {
    for (NSUInteger i=0; i<[resultData count]; i++) {
        [friends addObject:[resultData objectAtIndex:i]];
    }
} else {
    //[self showMessage:@"You have no friends."];
}

}

and I am implementing the required UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [friends count];
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:    (NSIndexPath *)indexPath
{
    //NSManagedObjectModel *friend [fetch

    FriendCell *cell = [tableView dequeueReusableCellWithIdentifier:   @"friendCell"];        

    cell.cellName.text = [friends objectAtIndex:indexPath.row];

return cell;
}

The problem is that the method 'cellForRowAtIndexPath' is being called before my data has arrived, how do you prevent the automatic initialization of the table view and only initialyse it when you have data for it ?

Upvotes: 0

Views: 6261

Answers (7)

JimmyJammed
JimmyJammed

Reputation: 9698

Don't set the tableview delegate and datasource until AFTER you have your data.

i.e.

-(void)viewDidLoad{
     [self apiGraphFriends];
     self.tableview.delegate = self;
     self.tableview.datasource = self;
}

I am assuming your method 'apiGraphFriends' doesn't use any background threading and isn't asynchronous. If it is, then just create a new method and put the datasource/delegate setting in there, then call it from a block in your apiGraphFriends method.

Upvotes: 1

aleph_null
aleph_null

Reputation: 5786

Your numberOfRowsInSection should return 0 if you don't have anything to display. After the data is loaded and ready to display, you should call reloadData on the tableView, and only then should the data be displayed. numberOfRowsInSection should now give the number of rows you loaded.

In short, you don't prevent the tableView from initializing. You initially tell it to display no data, and once your data is loaded, you tell it to display as many rows as you have.

Upvotes: 1

Scott Sherwood
Scott Sherwood

Reputation: 3128

Have you remembered to change the number of sections from 0 to at least 1?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

To fully test this you can use the following code

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Add your friend as you initialise the array
    NSMutableArray *array = [NSMutableArray arrayWithObjects:f1,nil];
}

- (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 [self.friends 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];
    }

    //change this to whatever you need
    NSString *friend = [self.friends objectAtIndex:indexPath.row];  
    cell.textLabel.text = friend;

    return cell;
}

Upvotes: 1

Glenn Smith
Glenn Smith

Reputation: 912

The tableview is always loaded on launch. Instead, after the data has finished loading, call

[self.tableView reloadData];

This tells the tableView to refresh, and it calls cellForRowAtIndexPath and all that jazz again.

Upvotes: 4

sosborn
sosborn

Reputation: 14694

You are so close!

- (void)viewDidLoad
{
  [self apiGraphFriends];
  [super viewDidLoad];
}

That should do it. If not, you can always call reloadData on the tableView.

Upvotes: -1

Ole Begemann
Ole Begemann

Reputation: 135548

how do you prevent the automatic initialization of the table view

You don't. The table view will automatically try to load its data when it is created and displayed. But that should not be a problem.

and only initialyse it when you have data for it.

Send a reloadData message to the table view once the data is ready.

Upvotes: 2

Antwan van Houdt
Antwan van Houdt

Reputation: 6991

simply call reloadData of the tableView once you got your data, the tableview will reload its data and thus recall all your datasource methods to get its data.

Upvotes: 0

Related Questions