Zakaria Darwish Zakaria Darwish - 6 months ago 30
iOS Question

cellForRowAtIndexPath not called inside UITabBarController

this question had been mentioned many time here but my case is slightly different what i am doing that there is a two UITableViewController inside UITabBarController when i switch to second UITableViewController the cellForRowAtIndextPath method is not fired to fill the UITableViewController with the data that are pulled from my server using AFNetworking after searching for many solution over the internet all the question that i found does not include UITabBarController such as
question 1 , question 2, question 3, question 4, question 5,

here is the code that i am trying to use :

#import "newsAndEventTableViewController.h"
#import "SplashViewController.h"
#import "sharedVariables.h"
#import"AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "MyGeeksTableViewController.h"
#import "geeksEvent.h"




@interface newsAndEventTableViewController ()
{
NSMutableArray *events;
geeksEvent *eventObject;
NSMutableArray *listOfEventsObjects;
}
@end

@implementation newsAndEventTableViewController



- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.delegate = self;

UIImage *image = [UIImage imageNamed:@"image.png"];
self.navigationItem.titleView = [[UIImageView alloc] initWithImage:image];


}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

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

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



return [events count];
}




- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath



{

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

[manager GET:@"http://myserver.com/get.php" parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {
// NSArray *products = [jsonDict objectForKey:@"images"];
// [products enumerateObjectsUsingBlock:^(id obj,NSUInteger idx, BOOL *stop){
// // NSString *productIconUrl = [obj objectForKey:@"imageUrl"];
//
// }];
//


NSLog(@"the response is: %@",responseObject);

events = [responseObject objectForKey:@"events"];



for (int i = 0; i < [events count];i++) {


eventObject = [events objectAtIndex:i];



[listOfEventsObjects addObject:eventObject];



}













}



failure:^(NSURLSessionTask *operation, NSError *error) {
NSLog(@"Error: %@", error);

UIAlertController * alert= [UIAlertController
alertControllerWithTitle:@"Error"
message:@"pls check your internet connection"
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* yesButton = [UIAlertAction
actionWithTitle:@"retry"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel your yes please button action here


}];
UIAlertAction* noButton = [UIAlertAction
actionWithTitle:@"No, Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Handel no, thanks button

}];

[alert addAction:yesButton];
[alert addAction:noButton];

[self presentViewController:alert animated:YES completion:nil];


}];







static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

// Display recipe in the table cell
geeksEvent *event = [events objectAtIndex:indexPath.row];


UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:@"placeholderimage"];

UILabel *eventTitle = (UILabel *)[cell viewWithTag:200];
eventTitle.text = event.eventTitle;
NSLog(@"the event title is: %@",event.eventTitle);

UILabel *eventDesc = (UILabel *)[cell viewWithTag:300];
eventDesc.text = event.eventShortDiscription;

// Assign our own background image for the cell
// UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];

// UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
// cellBackgroundView.image = background;
// cell.backgroundView = cellBackgroundView;


return cell;
}

/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:<#@"reuseIdentifier"#> forIndexPath:indexPath];

// Configure the cell...

return cell;
}
*/

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/

@end

Answer

The code inside the success block of the AFNetworking request is called asynchronously and that's why there's no data when displaying the tableView.

As a suggestion, you may want to move the AFNetworking request outside the tableView:cellForRowAtIndexPath: method (ex.: viewDidLoad) because this will trigger a request every time the app wants to display a cell, making the app unresponsive and consume the user bandwidth.

So using the suggestions above, the code will be:

#import "newsAndEventTableViewController.h"
#import "SplashViewController.h"
#import "sharedVariables.h"
#import"AFNetworking.h"
#import "UIWebView+AFNetworking.h"
#import "SDWebImageCompat.h"
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDownloader.h"
#import "MyGeeksTableViewController.h"
#import "geeksEvent.h"




   @interface newsAndEventTableViewController ()
  {
    NSMutableArray *events;
    geeksEvent *eventObject;
    NSMutableArray *listOfEventsObjects;
   }
   @end

@implementation newsAndEventTableViewController



- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.delegate = self;

    UIImage *image = [UIImage imageNamed:@"image.png"];
    self.navigationItem.titleView = [[UIImageView alloc] initWithImage:image];


    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    [manager GET:@"http://myserver.com/get.php" parameters:nil progress:nil success:^(NSURLSessionTask *task, id responseObject) {

        NSLog(@"the response is: %@",responseObject);

        events = [responseObject objectForKey:@"events"];

        for (int i  = 0; i < [events count];i++) {
            eventObject  = [events objectAtIndex:i];

            [listOfEventsObjects addObject:eventObject];
        }

        // Calling reload data after request is done
        [self.tableView reloadData];
      }

      failure:^(NSURLSessionTask *operation, NSError *error) {
         NSLog(@"Error: %@", error);

         UIAlertController * alert=   [UIAlertController
                                       alertControllerWithTitle:@"Error"
                                       message:@"pls check your internet connection"
                                       preferredStyle:UIAlertControllerStyleAlert];

         UIAlertAction* yesButton = [UIAlertAction
                                     actionWithTitle:@"retry"
                                     style:UIAlertActionStyleDefault
                                     handler:^(UIAlertAction * action)
                                     {
                                         //Handel your yes please button action here


                                     }];
         UIAlertAction* noButton = [UIAlertAction
                                    actionWithTitle:@"No, Cancel"
                                    style:UIAlertActionStyleDefault
                                    handler:^(UIAlertAction * action)
                                    {
                                        //Handel no, thanks button

                                    }];

         [alert addAction:yesButton];
         [alert addAction:noButton];

         [self presentViewController:alert animated:YES completion:nil];
      }];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

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

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Display recipe in the table cell
    geeksEvent *event = [events objectAtIndex:indexPath.row];


    UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
    recipeImageView.image = [UIImage imageNamed:@"placeholderimage"];

    UILabel *eventTitle = (UILabel *)[cell viewWithTag:200];
    eventTitle.text = event.eventTitle;
    NSLog(@"the event title is: %@",event.eventTitle);

    UILabel *eventDesc = (UILabel *)[cell viewWithTag:300];
    eventDesc.text = event.eventShortDiscription;

    // Assign our own background image for the cell
    // UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];

    //    UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
    //    cellBackgroundView.image = background;
    //    cell.backgroundView = cellBackgroundView;


    return cell;
}

@end