在 UITabBarController 内未调用 cellForRowAtIndexPath

Posted

技术标签:

【中文标题】在 UITabBarController 内未调用 cellForRowAtIndexPath【英文标题】:cellForRowAtIndexPath not called inside UITabBarController 【发布时间】:2016-05-22 13:38:44 【问题描述】:

这个问题在这里已经被多次提及,但我的情况与我所做的略有不同,当我切换到第二个 UITableViewController 时,UITabBarController 中有两个 UITableViewController 不会触发 cellForRowAtIndextPath 方法来填充 UITableViewController 的数据在互联网上搜索了许多解决方案后,使用 AFNetworking 从我的服务器中提取我发现的所有问题都不包括 UITabBarController,例如 question 1,question 2,question 3,question 4,question 5,

这是我尝试使用的代码:

#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

【问题讨论】:

你能在 numberOfRowsInsection 中做一个 [events count] 的 NSLog 如果我在 RowForIndexPath 中执行 AFHTTPrequest 或使用 viewDidLoad,即使在两种情况下,它也会给我零 可能是因为您的请求返回零元素还是我错了? 数据库中没有数据,因为我在浏览器中尝试了 api 它给了我结果 【参考方案1】:

AFNetworking 请求的success 块内的代码是异步调用的,这就是显示tableView 时没有数据的原因。

作为建议,您可能希望将 AFNetworking 请求移到 tableView:cellForRowAtIndexPath: 方法之外(例如:viewDidLoad),因为这将在应用程序每次想要显示单元格时触发请求,从而使应用程序无响应并消耗用户带宽。

所以使用上面的建议,代码将是:

#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

【讨论】:

即使我在 viewdidload 内尝试或使用 viewwillappear 发生同样的事情 请注意,我在请求结束后添加了一个reloadData 调用。这将在使用请求中的数据更新 events 数组后触发 tableView 显示。

以上是关于在 UITabBarController 内未调用 cellForRowAtIndexPath的主要内容,如果未能解决你的问题,请参考以下文章

超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调

Got Timeout - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调

JEST:“在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调。”,尽管它已经配置

jasmine:在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时时间内未调用异步回调

带有 Typescript 错误的玩笑:超时 - 在 jest.setTimeout.Timeout 指定的 5000 毫秒超时内未调用异步回调

使用 Node 进行 Jest 测试 - 超时 - 在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调