I have a UITableView with a list of stories and a cell at the bottom that loads more stories. I am trying to make the "More Stories..." cell deselect and change its text to "Loading..." when clicked. I have searched all over the internet and all over stackoverflow and I cant figure out why my code isnt working right. Right now, when the "More Stories..." cell is clicked, it stays selected and doesnt ever change its text.
For those asking, moreStories adds 25 new stories to the bottom of the table view.
Original Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
if (storyIndex == [stories count]) {
UITableViewCell *moreCell = [tableView dequeueReusableCellWithIdentifier:@"more"];
if (moreCell == nil) {
moreCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"more"] autorelease];
} // Set up the cell
moreCell.textLabel.text = @"Loading...";
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self moreStories];
} else {
NSLog(@"%@",[[stories objectAtIndex: storyIndex] objectForKey: @"link"]);
webViewController *webController;
webController = [[webViewController alloc] initWithURLPassed:[[stories objectAtIndex: storyIndex] objectForKey: @"link"]];
[self.navigationController pushViewController:webController animated:YES];
[webController release];
webController =nil;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}
Updated but still not working correctly. Now it finally deselects the cell and changes the text to "Loading...", but only after moreStories finishes downloading all of the stories. Obviously, I want the text to be "Loading..." while the stories are downloading 1/4/10 ~9pm
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath开发者_如何学运维 *)indexPath {
// Navigation logic
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
if (storyIndex == [stories count]) {
UITableViewCell *moreCell = [tableView cellForRowAtIndexPath:indexPath];
moreCell.textLabel.text = @"Loading...";
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSArray *arr = [[NSArray alloc] initWithObjects:indexPath,nil];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
[self moreStories];
} else {
NSLog(@"%@",[[stories objectAtIndex: storyIndex] objectForKey: @"link"]);
webViewController *webController;
webController = [[webViewController alloc] initWithURLPassed:[[stories objectAtIndex: storyIndex] objectForKey: @"link"]];
[self.navigationController pushViewController:webController animated:YES];
[webController release];
webController =nil;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
}
}
[tableView dequeueReusableCellWithIdentifier:@"more"]
tells the table view to give you a different cell, one that's in the reuse queue and out of what's being displayed. Moreover, the moreCell == nil
condition generates a brand new cell when no reusable cell was available to dequeue. This pattern is only intended for use by the table view data source when generating table cells for display.
You need to use [tableView cellForRowAtIndexPath:indexPath]
instead to get the cell that was actually selected.
UITableViewCell *moreCell = [tableView cellForRowAtIndexPath:indexPath];
moreCell.textLabel.text = @"Loading...";
EDIT: based on your update it looks like, as aBitObvious says in the comments, the URL load request is blocking the UI from being updated. As you update your UI, try starting a new thread and load the data within that thread, so that your UI can update undisturbed.
I went ahead and made a very simple version of what you're trying to accomplish. See if this helps at all. The way I made this happen was I went ahead and changed the UITableView's datasource. Which ultimately you may be doing in order to load in more stories. The key thing to remember is if you're changing the datasource you'll need to reload the tableView.
- (void)viewDidLoad {
NSArray *array = [[NSArray alloc] initWithObjects:@"Story 1", @"Story 2", @"Story 3", @"Story 4", @"Story 5", @"More Stories", nil];
self.stories = array;
[array release];
[super viewDidLoad];
}
//TableView DataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [stories count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] autorelease];
}
cell.textLabel.text = [stories objectAtIndex:[indexPath row]];
return cell;
}
//TableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath row] == [stories count] - 1) {
//Get more stories
[table deselectRowAtIndexPath:indexPath animated:YES];
NSArray *array = [[NSArray alloc] initWithObjects:@"Story 1*", @"Story 2*", @"Story 3*", @"Story 4*", @"Story 5*", @"Loading...", nil];
self.stories = array;
[array release];
NSArray *arr = [[NSArray alloc] initWithObjects:indexPath,nil];
[table beginUpdates];
[table reloadRowsAtIndexPaths:arr withRowAnimation:UITableViewRowAnimationFade];
[table endUpdates];
}
else {
//Call your methods to load the stories.
}
精彩评论