I am using a UITableView and I'm noticing that the cells in my tableview are getting progresively bolder as I scroll, it is overwriting the contents and I want to stop this but can't see where I'm going wrong.
On my UITableView, for some reason when I scroll the contents of the tableview get messed up with the the manually created UILabel.
I require a manual UILabel because I need to have custom cells later on.
As I scroll up and down, the labels get progressively bolder and bolder; they always overlap and sometimes even affects rows lower down (even before they are in the viewport).
If I keep doing it, the cell contents become unintelligable.
This only happens if there the backgroundColor is not set as clearColor
.
I have attempted [cellLabel setClearsContextBeforeDrawing:YES];
and [self.tableView setClearsContextBeforeDrawing:YES];
to no effect.
If I use cell.textLabel.text
then the problem seems to go away.
Code and an image sample follows.
// Simple table view
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
//[self configureCell:cell atIndexPath:indexPath];
NSString *txt = @"Product";
//cell.textLabel.text = txt;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, cell.frame.size.height)];
UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
[cellLabel setText:txt];
[cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
[cellLabel setBackgroundColor:[UIColor clearColor]];
[cellView addSubview:cellLabel];
[cellLabel release];
[cell.contentView addSubview:cellView];
[cellView release];
return cell;
}
Image follows;
![image of uitableview][1]
[1]: http://i.stack.imgur.com/5lNy6.png
// Edit to include context
I am using a dictionary to display the contents of the UITableViewCells.
I have attempted to do the following;
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[self configureCell:cell atIndexPath:indexPath];
} // end if
// Configure the cell...
//
// Moved to inside the cell==nil
return cell;
}
-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
// Get the txt from the Dictionary/Plist... *removed due verboseness*
UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
[cellLabel setText:txt];
[cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
[cellLabel setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:cellLabel];
[cellLabel release];
}
This, although it fixes the problem of overwriting -- it causes a problem -- it makes labels repeatedly appear in totally random places -- the following is just an example, other fields and labels also repeat.
See picture below;
// cell reuse
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
returned you the cell already been used, it already has an UILabel subview and you are adding another over it. Put the adding subviews at the section
if (cell == nil) { //cell initialization
and edit the subviews as needed after the cell initialization, you can access them by tag for example.
You are adding the label to the same reused cell every time, that is why it is getting bolder. When you use dequeueReusableCellWithIdentifier, you are grabbing a cell that has already been displayed on the screen, which is the correct thing to do, but you have already put a label on it. As the label will be in the same position relative to the cell each time, and the same color etc.. (the only dynamic element will be the text), you should set all this up only once.
My preferred solution is to create a custom cell with the properties that you want. So in this case, you would create
@interfacce MyCustomCell : UITableViewCell
@property (nonatomic) UILabel *cellLabel;
@end
Give it a property UILabel *cellLabel, and do all the code you have above apart from setting the labels text in the init of MyCustomCell.m, replace any instances of cell with self, for example:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
self.cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
[self.cellLabel setText:txt];
[self.cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
[self.cellLabel setBackgroundColor:[UIColor clearColor]];
}
return self;
}
Now in your cellForRowAtIndexPath use MyCustomCell, where you check if cell == nil, you might want to also check the cell label:
if(cell == nil || cell.cellLabel == nil)
Initialise it in exactly the same way:
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
now, all you need to do is set:
cell.cellLabel.text = ....;
your code in cellForRowAtIndexPath is a lot cleaner, memory efficient and and you will not get your bug.
Remember to set your cell to be of type MyCustomCell in interface builder.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = (UITableViewCell*)[self.YourTableName dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
}
return cell;
}
use ReusablecellIdentifier nil so it working correctly.....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With