在 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 毫秒超时内未调用异步回调