UITableview dequeueReusableCellWithIdentifier and scroll-freezing issues
So I have some issues with my tableview
. I have a 开发者_如何学运维custom label
that I put into a tableview cell
to add a little better graphics than the standard UItableviewcell
. However, I was running into my first problem,
the text labels that I had on the
cells
were changing with and over writing each other upon scrolling, only when thecells
had moved off screen and then came back. Upon some research I found that maybe it had something to do withdequeueReusableCellWithIdentifier:
so I adjusted my code. this is where problem two comes in.When I load the
table
everything is in its right place, correct looking and all. However when I start toscroll
down I can get to all of my cells except the last one, it will go to the very bottom of the 8th cell and freeze, but I should have 9 cells loaded.
I am quite confused by some of this, could anyone provide some code or guidance to help me along?
Thanks.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Run");
CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
static NSString *CellIdentifier = @"Cell";
UILabel *label;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *keys = [[appDelegate rowersDataStore] allKeys];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// Configure the cell...
label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease];
label.font = [UIFont boldSystemFontOfSize:16];
label.backgroundColor = [UIColor clearColor];
label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5];
label.shadowOffset = CGSizeMake(0,1);
label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0];
switch (indexPath.section) {
case 0:
label.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30);
label.textAlignment = UITextAlignmentCenter;
break;
case 1:
label.textAlignment = UITextAlignmentLeft;
UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"];
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage];
cell.accessoryView = accessoryView;
[accessoryView release];
break;
}
UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame];
UIImage* img = [UIImage imageNamed:@"odd_slice.png"];
imgView.image = img;
cell.backgroundView = imgView;
[imgView release];
//Selected State
UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"];
UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame];
selectionView.image = selectionBackground;
cell.selectedBackgroundView = selectionView;
[selectionView release];
}
switch (indexPath.section) {
case 0:
[label setText:@"Click to add new rower"];
break;
case 1:
[label setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]];
break;
}
//Adds Text
[cell addSubview:label];
return cell;
}
I see several issues here. First, the general structure of this method should be...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
// Attempt to dequeue the cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// If cell does not exist, create it, otherwise customize existing cell for this row
if (cell == nil) {
// Create cell
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// Configure cell:
// *** This section should configure the cell to a state independent of
// whatever row or section the cell is in, since it is only executed
// once when the cell is first created.
}
// Customize cell:
// *** This section should customize the cell depending on what row or section
// is passed in indexPath, since this is executed every time this delegate method
// is called.
return cell;
}
Basically, UITableView
uses a single UITableViewCell
instance to draw every cell in the table view. So, when you first create this cell, you should configure it to a state that is common to all cells that will use this instance, independent of whatever row or section is passed in indexPath
. In your example, this involves creating the label, image, and background image instances and adding them as subviews to the cell.
Once the cell is created (aka outside the if (cell == nil)
statement), you should customize its properties according to how the cell should look for the specific row and section contained in indexPath
. Since you want to access your custom label in this part of the code, I assigned a tag
value to it so that we can access it beyond the code segment where it was created using viewWithTag:
. Once we have the label, we can customize it according to the section as well as do anything else we want, such as customize the accessory view.
I slightly modified/cleaned up your code below. This is by far not the most efficient or elegant way to do what you want to do, but I was trying to keep as much of your code as possible. I haven't tested this, but if you try it it should work:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Run");
CoCoachAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSArray *keys = [[appDelegate rowersDataStore] allKeys];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// Configure the cell...
UILabel *label;
label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 15, cell.bounds.size.width - 10, 30)] autorelease];
label.font = [UIFont boldSystemFontOfSize:16];
label.opaque = NO;
label.backgroundColor = [UIColor clearColor];
label.shadowColor = [UIColor colorWithWhite:1.0 alpha:0.5];
label.shadowOffset = CGSizeMake(0,1);
label.textColor = [UIColor colorWithRed:0x4c/255.0 green:0x4e/255.0 blue:0x48/255.0 alpha:1.0];
label.tag = 100;
[cell addSubview:label];
[label release];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:cell.frame];
UIImage* img = [UIImage imageNamed:@"odd_slice.png"];
imgView.image = img;
cell.backgroundView = imgView;
[imgView release];
//Selected State
UIImage *selectionBackground = [UIImage imageNamed:@"row_selected.png"];
UIImageView *selectionView = [[UIImageView alloc] initWithFrame:cell.frame];
selectionView.image = selectionBackground;
cell.selectedBackgroundView = selectionView;
[selectionView release];
}
UILabel *lbl = (UILabel *)[cell viewWithTag:100];
switch (indexPath.section) {
case 0:
cell.accessoryView = nil;
lbl.frame = CGRectMake(0, 15, cell.bounds.size.width - 10, 30);
lbl.textAlignment = UITextAlignmentCenter;
[label setText:@"Click to add new rower"];
break;
case 1:
UIImage *accessoryImage = [UIImage imageNamed:@"content_arrow.png"];
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:accessoryImage];
cell.accessoryView = accessoryView;
[accessoryView release];
lbl.frame = CGRectMake(20, 15, cell.bounds.size.width - 10, 30);
lbl.textAlignment = UITextAlignmentLeft;
[lbl setText:[[[appDelegate rowersDataStore] objectForKey:[keys objectAtIndex:indexPath.row]] objectForKey:@"Name"]];
break;
}
return cell;
}
精彩评论