I am trying to create a UITableViewCell
that contains a UIScrollView
that is able to scroll horizontally for each cell in the UITableView
.
Everything shows correctly and works well. However, when I scroll constantly up and down on the UITableView
, memory usage goes up and up and up and up..... which I think means that I am constantly adding the custom elements over each over when the UITableViewCell
is being reused. I would like to know how I can stop this from happening.
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell...
NSDictionary *cellDictionary = [xmlMArray objectAtIndex:indexPath.row];
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// code
codeString = [[UILabel alloc] initWithFrame:CGRectMake(15.0, 0.5, 70.0, 40.0)];
codeString.text = [cellDictionary objectForKey:@"Code"];
codeString.backgroundColor = [UIColor clearColor];
// series
addressString = [[UILabel alloc] initWithFrame:CGRectMake(220.0, 10.5, addressString.frame.size.width, 50.0)];
addressString.text = [NSString stringWithFormat:@"PC %@: %@",[cellDictionary objectForKey:@"Number"] ,[cellDictionary objectForKey:@"Street"]];
[addressString sizeToFit]; // Dynamic UILabel width
addressString.backgroundColor = [UIColor clearColor];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIScrollView *scrollCell = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, cell.frame.size.width, cell.frame.size.height)];
[scrollCell setContentSize:(CGSizeMake((220.0 + addressString.frame.size.width)+15, cell.frame.size.height))];
[scrollCell addSubview:codeString];
[scrollCell addSubview:addressString];
[cell addSubview:scrollCell];
return cell;
}
There seems to be two problems here. I'll try to explain what's actually happening, but you should follow mbm29414's answer on what to do.
In the first part of this method, you are asking for a UITableViewCell
using the identifier:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
The next part is to check if you received a cell with this call:
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
This means that if your first line of code DID NOT return a cell-object, then you are instantiating a new one.
Later on in your method, you are instantiating yet another cell:
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
UIScrollView *scrollCell (...)
This way you might not actually be reusing the cells, I'm not sure. At the very least, it should not be there. You potentionally allocate double the space each time. Remove the last instantiation, and that should probably help a little.
The other problem, I think, is that you're adding scrollView and UILabels to your cells' subviews. Your circle of life:
When your cell is brought back from the dead during [tableView dequeueReusable..]
, they still contain the UIScrollView with the UILabel. Your code does not take advantage of that, but rather ignores it. This means that you are adding an ADDITIONAL scrollView with labels into your cell. If you scroll up and down a lot, this means that one single cell can possibly contain 50 different scrollViews, all of them taking the same amount of processing.
This is what happens next:
To solve this, you should do as mbm29414 suggested, to make your own subclass of UITableViewCell. That way, you can say cell.codeString.text=@"blah";