UITableView repeating cells when scrolled
When i scroll down my UITableView, it starts showing me the same cells that i've already seen, and scrolling around a bit continues to put cells in the wrong place.
Here's the code i'm using. If anything additional is needed then let me know:
.h
@interface HomeViewController : UITableViewController {
int numberOfRows;
NSArray *allVaults;
}
@property (nonatomic, assign) int numberOfRows;
@property (nonatomic, retain) NSArray *allVaults;
@end
.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSString *vaultsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Vaults"];
NSFileManager *fileManager = [NSFileManager defaultManager];
self.allVaults = [fileManager contentsOfDirectoryAtPath:vaultsPath error:nil];
numberOfRows = [self.allVaults count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autoreleas开发者_StackOverflow社区e];
NSString *vaultsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Vaults"];
NSString *dictionaryPath = [NSString stringWithFormat:@"%@/%@",
vaultsPath,
[self.allVaults objectAtIndex:indexPath.row]];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:dictionaryPath];
cell.backgroundView = [AHCellCreation backgroundView];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.selectedBackgroundView = [AHCellCreation selectedBackgroundView];
cell = [AHCellCreation createCellWithDictionary:dictionary Cell:cell];
}
return cell;
}
Any help is appreciated!
EDIT 1: Image to show what happens when i move most code outside the (cell == nil) if statement:
Before:
After:
EDIT 2:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 82;
}
It looks as if you are only setting the cell content when the you're getting a nil back from dequeueReusableCellWithIdentifier. You need to set the cell contents every time, not just when you need to create a new cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
AHCell *cell = (AHCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
// create a new cell if there isn't one available to recycle
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [AHCell blankCell];
}
// set the contents of the cell (whether it's a new one OR a recycled one)
NSString *vaultsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Vaults"];
NSString *dictionaryPath = [NSString stringWithFormat:@"%@/%@",
vaultsPath,
[self.allVaults objectAtIndex:indexPath.row]];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:dictionaryPath];
cell.backgroundView = [AHCellCreation backgroundView];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.selectedBackgroundView = [AHCellCreation selectedBackgroundView];
// cell = [AHCellCreation createCellWithDictionary:dictionary Cell:cell];
[cell populateAHCellWithDictionary: dictionary];
return cell;
}
Update updated code to address second issue. Rework AHCell so that the class method, e.g. blankCell returns a new cell with the subviews set up and the instance method, e.g. populateAHCellWithDictionary: sets the content.
In that case AHCellCreation
class must add the subviews to the cell and then set the text in one go? You need to layout the cell inside the if statement (add the subviews, UILabels, UIImageView etc, and set their frames etc). And set the content outside the if statement.
Basically whatever doesn't change in each row put inside the if statement, but what changes from row to row put outside the if statement.
This is because the code inside the if statement is only reached when the cell is created, almost always its the cells that are visible on the screen when the Table view loads are created.
When you scroll down the cells that disappear off the top of the screen are reused, and put at the bottom. This means that is you have 100 rows, it won't create 100 cells (it only creates the number of cells that can be visible on the screen at a time and the reuses those) , as this would consume a lot of memory, and the scrolling wouldn't be as smooth.
精彩评论