问题
Everything works fine when the view that holds my table is the main (first) view.
However, when it's not the first view and I switch into that view, my table does not load data and I get an empty table.
Using NSLog I can tell that the program is not invoking numberOfRowsInSection and cellForRowAtIndexPath.
I have <UITableViewDataSource, UITableViewDelegate>
, IBOutlet UITableview *tableView
all declared. They are also connected in the InterfaceBuilder.
I tried using viewWillAppear
and [tableView reloadData]
but that did not help.
I'm new to iPhone development and your help is appreciated!
UPDATE:
I tried [tableView reloadData] but nothing happened.
I'm not releasing tableView anywhere but dealloc.
Here is some code:
appDelegate
//
// tpbAppDelegate.m
// tpb
#import "listController.h"
#import "tpbAppDelegate.h"
#import "tpbViewController.h"
@implementation tpbAppDelegate
@synthesize window;
@synthesize viewController;
@synthesize navController;
@synthesize toolbar;
@synthesize btnMyLoc;
@synthesize places; //array that holds data from the XML file
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//add places into an array that can be used by other views (Table)
rssList = [[NSMutableArray alloc] initWithCapacity:1];
NSString *paths = [[NSBundle mainBundle] resourcePath];
NSString *xmlFile = [paths stringByAppendingPathComponent:@"tourplay.xml"];
NSURL *xmlURL = [NSURL fileURLWithPath:xmlFile isDirectory:NO];
NSLog(@"DATA URL: %@", xmlURL);
NSXMLParser *firstParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[firstParser setDelegate:self];
[firstParser parse];
// Resize window for toolbar:
CGRect frame = viewController.view.frame;
frame.size.height -= toolbar.frame.size.height;
viewController.view.frame = frame;
//[window addSubview:viewController.view];
navController.viewControllers = [NSArray arrayWithObject:viewController];
navController.view.frame = frame;
[window addSubview:navController.view];
[window makeKeyAndVisible];
}
- (IBAction)showList:(id)sender{
//Switch to table view on segment control change
UISegmentedControl *segmentControl = (UISegmentedControl *)sender;
NSString *curSelection = [NSString stringWithFormat:@"%d", [segmentControl selectedSegmentIndex]];
//[segmentControl titleForSegmentAtIndex: [segmentControl selectedSegmentIndex]]];
NSLog(@"pressed button %@", curSelection);
if ([curSelection isEqualToString:@"1"]){
NSLog(@"TABLE SELECTED");
listController *listTable = [[listController alloc] init];
[navController pushViewController:listTable animated:YES]; //SWITCH TO TABLE VIEW (listController)
} else {
tpbViewController *tpb = [[tpbViewController alloc] init];
NSLog(@"MAP SELECTED");
[navController pushViewController:tpb animated:YES];
}
}
#pragma mark Praser Methods
//Parse XML into an array
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
//NSLog(@"Started parsing");
if ([elementName compare:@"tour_point"] == NSOrderedSame) {
[self.places addObject:[[NSDictionary alloc] initWithObjectsAndKeys:
//[attributeDict objectForKey:@"tour_point_id"],@"tour_point_id",
[attributeDict objectForKey:@"name"],@"name",
[attributeDict objectForKey:@"tour_html"],@"tour_html",
[attributeDict objectForKey:@"audio_src"],@"audio_src",
nil]];
} else if ([elementName compare:@"title"] == NSOrderedSame) {
titlename = (NSString *)[attributeDict objectForKey:@"titlename"];
NSLog(@"Done parsing %@ points", titlename);
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@"Parser end");
[parser release];
}
- (void)dealloc {
[viewController release];
[rssList release];
[places release];
[toolbar release];
[window release];
[super dealloc];
}
@end
listController.h - table class
#import <UIKit/UIKit.h>
@interface listController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSMutableArray *places;
NSString *titlename;
}
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@end
listController.m - table implemenation
//
// listController.m
// tpb
//
//
#import "listController.h"
#import "tpbAppDelegate.h"
@implementation listController
@synthesize tableView;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
//- (void)viewWillAppear {
tpbAppDelegate *delegate = (tpbAppDelegate *)[[UIApplication sharedApplication] delegate];
places = delegate.places;
NSLog(@"Loaded table view");
[super viewDidLoad];
// [tableView reloadSectionIndexTitles];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tv {
NSLog(@"Number of secions");
return 1;
}
- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
NSLog(@"GETTING COUNT");
return [places count];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Assigning Cells");
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (nil == cell) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [[places objectAtIndex:indexPath.row] objectForKey:@"name"];
//NSLog(@"count %@", [[places objectAtIndex:indexPath.row] objectForKey:@"name"]);
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"ROW clicked");
[tv deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
NSLog(@"Unloaded tableview");
}
- (void)dealloc {
[tableView release];
[places release];
[super dealloc];
}
@end
-- So far, I know that viewDidLoad loads, but the table meathods such as cellRowAtIndexPath are not invoked.
回答1:
- (IBAction)showList:(id)sender{
//Switch to table view on segment control change
UISegmentedControl *segmentControl = (UISegmentedControl *)sender;
NSString *curSelection = [NSString stringWithFormat:@"%d", [segmentControl selectedSegmentIndex]];
//[segmentControl titleForSegmentAtIndex: [segmentControl selectedSegmentIndex]]];
NSLog(@"pressed button %@", curSelection);
if ([curSelection isEqualToString:@"1"]){
NSLog(@"TABLE SELECTED");
listController *listTable = [[listController alloc] init];
//Try this
listTable.places = self.places; // set the array contents here and check
[navController pushViewController:listTable animated:YES]; //SWITCH TO TABLE VIEW (listController)
} else {
tpbViewController *tpb = [[tpbViewController alloc] init];
NSLog(@"MAP SELECTED");
[navController pushViewController:tpb animated:YES];
}
}
Dont forget to write the accessors in ListController for places array. And let me know what happens.
回答2:
This problem happens when you do not link the datasource and delegate of table view to the file's owner in the interface builder. Cross check once again in the interface builder see the connections for datasource and delegate of tableview are properly made with files owner and you have not mistakenly linked them with view.
Besides tell one thing more if
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
is getting called. If it is then you have passed 0 in this. Well a '0' is not acceptable from iphone-sdk-3.0 and later.
Thanks,
Madhup
回答3:
When you go to display your tableview, call the reloadData method on it; if your datasource/delegate is assigned to the correct object then that will trigger the table view to ask the datasource/delegate for its cells, and it should display at that point.
来源:https://stackoverflow.com/questions/2597576/uitableview-gives-empty-table-does-not-load-data