UITableViewCell repeats after scrolling - iphone

I am not sure why my UITableViewCell's are repeating after the user scrolls?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
ChartlyCell *cell = (ChartlyCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[[ChartlyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell = [[[ChartlyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andDelegate:self] autorelease];
}
ChartlyObject *myChartlyObject;
myChartlyObject = [self.items objectAtIndex:indexPath.row];
cell.usernameLabel.text = myChartlyObject.userName;
cell.bodyLabel.text = myChartlyObject.chart_message;
[cell.messageLabel setText: myChartlyObject.chart_message];
cell.timeLabel.text = [Utils toShortTimeIntervalStringFromStockTwits: myChartlyObject.created_at];
[cell.chartImage loadImageFromURL:[NSURL URLWithString:myChartlyObject.imageThumbnail]];
return cell;
}
This is how the cell is being created:
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier andDelegate:(id<NLabelDelegate>)ndelegate{
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
// Initialization code
CGRect rect;
rect = CGRectMake(77, 5, 200, 20); //CGRectMake(10, 5, 200, 20);
usernameLabel = [[UILabel alloc] initWithFrame:rect];
//usernameLabel.backgroundColor = backgroundColor;
usernameLabel.font = [Utils getBoldSystemFontWithSize:14];
usernameLabel.textColor = [UIColor colorWithRed:.368 green:.741 blue:.784 alpha:1];
[self.contentView addSubview: usernameLabel];
rect = CGRectMake(277, 5, 38, 20);
timeLabel = [[UILabel alloc] initWithFrame:rect];
timeLabel.textAlignment = UITextAlignmentRight;
//timeLabel.backgroundColor = backgroundColor;
timeLabel.font = [Utils getBoldSystemFontWithSize:14];
timeLabel.textColor = [UIColor colorWithRed:.98 green:.65 blue:.01 alpha:1];
[self.contentView addSubview: timeLabel];
/*rect = CGRectMake(77, 25, 238, 68); //CGRectMake(10, 50, 238, 68);
bodyLabel = [[UILabel alloc] initWithFrame:rect];
bodyLabel.font = [Utils getSystemFontWithSize:10];
bodyLabel.numberOfLines = 3;
bodyLabel.lineBreakMode = UILineBreakModeWordWrap;
bodyLabel.textColor = [UIColor blackColor];
bodyLabel.backgroundColor = [UIColor clearColor];
[self.contentView addSubview: bodyLabel];*/
rect = CGRectMake(77, 25, 238, 68);
messageLabel = [[NLabel alloc] initWithFrame:rect andDelegate:ndelegate];
[messageLabel setOpaque:NO];
[messageLabel setBackgroundColor: [UIColor blackColor]];
//[messageLabel setTotalheight:68];
[self.contentView addSubview: messageLabel];
rect = CGRectMake(13, 10, 48, 48);
chartImage = [[AsyncImageView alloc]initWithFrame:rect];
[self.contentView addSubview: chartImage];
}
return self;
}
UPDATE:
What is odd, is that if I uncomment the bodyLabel block and comment out the messageLabel block the repeating cells don't appear anymore. I am not sure why and would still like to find a resolution
UPDATE #2
Only messageLabel gets repeated. All of the other labels do NOT repeat. Why is this?

Because you are re-using tablecells for proper memory management as you should be doing via dequeueReusableCellWithIdentifier :) This way you don't have a unique cell for every single cell you need. Instead you only have about 5 or 6 that get re-used over and over during scrolling.
When the cell comes back into view, you need to reset the state (i.e. update the info, labels, images, etc) of each cell based on whatever cell came into view.

One thing you can do is to remove all the views in the cell.contentView after you create the cell or dequeue it. Alternatively, you can create a custom cell with attributes for the labels that you can set to different values when you scroll down.

Related

Custom UITableViewCell is empty, although cell from heightForRowAtIndexPath is correct

Sorry, I am missing it. I have a beautiful table with correct (variable) row heights. But all the cells are blank. Three labels should be populated in each cell.
UPDATE: FIX IS BELOW
#implementation MasterTableCell
#synthesize labelDesc;
#synthesize labelDuration;
#synthesize labelName;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// name
CGRect frameTextLabel = CGRectMake(8, 2, 244, 25);
labelName = [[UILabel alloc] initWithFrame:frameTextLabel];
labelName.lineBreakMode = UILineBreakModeTailTruncation;
labelName.font = [UIFont boldSystemFontOfSize:17.0];
labelName.textColor = [UIColor blackColor];
// description
labelDesc = [[UILabel alloc] init];
labelDesc.lineBreakMode = UILineBreakModeWordWrap;
labelDesc.numberOfLines = 0;
labelDesc.textColor = [UIColor grayColor];
labelDesc.font = [UIFont systemFontOfSize:14.0f];
labelDesc.backgroundColor = [UIColor blueColor];
// duration
CGRect frame = CGRectMake(252, 5, 40, 20);
labelDuration = [[UILabel alloc] initWithFrame:frame];
labelDuration.font = [UIFont boldSystemFontOfSize:14.f ];
labelDuration.textAlignment = UITextAlignmentRight;
labelDuration.backgroundColor = [UIColor redColor]; // to see it
[self.contentView addSubview:labelName];
[self.contentView addSubview:labelDesc];
[self.contentView addSubview:labelDuration];
}
return self;
}
#end
And
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"RecipeCell";
MasterTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[MasterTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Recipe *recipeAtIndex = [sortedArray objectAtIndex:indexPath.row];
cell.labelName.text = #"Test1";
cell.labelDesc.text = #"Test2";
cell.labelDuration.text = [TBCommon formattedStringforDuration:recipeAtIndex.duration withDelimeter:#":"];
CGRect frameDescLabel = CGRectMake(8, 25, 284, [self heightForDescriptionFrame:recipeAtIndex.description]);
cell.labelDesc.frame = frameDescLabel;
return cell;
}
FIX
#import "MasterTableCell.h"
#implementation MasterTableCell : UITableViewCell
#synthesize labelDesc;
#synthesize labelDuration;
#synthesize labelName;
- (void)awakeFromNib
{
[super awakeFromNib];
// name
CGRect frameTextLabel = CGRectMake(8, 2, 244, 25);
labelName = [[UILabel alloc] initWithFrame:frameTextLabel];
labelName.lineBreakMode = UILineBreakModeTailTruncation;
labelName.font = [UIFont boldSystemFontOfSize:17.0];
labelName.textColor = [UIColor blackColor];
// description
labelDesc = [[UILabel alloc] init];
labelDesc.lineBreakMode = UILineBreakModeWordWrap;
labelDesc.numberOfLines = 0;
labelDesc.textColor = [UIColor grayColor];
labelDesc.font = [UIFont systemFontOfSize:14.0f];
// duration
CGRect frame = CGRectMake(252, 5, 40, 20);
labelDuration = [[UILabel alloc] initWithFrame:frame];
labelDuration.textColor = [UIColor colorWithRed:38.0/255.0 green:111.0/255.0 blue:208.0/255.0 alpha:1];
labelDuration.font = [UIFont boldSystemFontOfSize:14.f ];
labelDuration.textAlignment = UITextAlignmentRight;
[self.contentView addSubview:labelName];
[self.contentView addSubview:labelDesc];
[self.contentView addSubview:labelDuration];
}
#end
And
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MasterTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Recipe *recipeAtIndex = [sortedArray objectAtIndex:indexPath.row];
cell.labelName.text = recipeAtIndex.name;
cell.labelDesc.text = recipeAtIndex.description;
cell.labelDuration.text = [TBCommon formattedStringforDuration:recipeAtIndex.duration withDelimeter:#":"];
CGRect frameDescLabel = CGRectMake(8, 25, 284, [self heightForDescriptionFrame:recipeAtIndex.description]);
cell.labelDesc.frame = frameDescLabel;
return cell;
}
If you're using Storyboards, initWithStyle will never be called. Move the label creation code into awakeFromNib.
You can get rid of the whole if (cell == nil) part too because dequeueReusableCell will ALWAYS return a cell.
Do you think that your table view delegate/datasource method are actually being called. Trying putting a break point in cellForRowAtIndexPath method to verify that. If breakpoint's not hit it means your delegate and datasource are not set. Set those.
Another thing that I noticed is that you have not set the frame for your labelDesc instance variable. That's worth looking at.
When I was setting up my custom cell subclasses, the tutorial I was following had me set the frames in a separate method called layoutSubviews. For you, it would look like
- (void) layoutSubviews
{
[super layoutSubviews];
labelName.frame = CGRectMake(8, 2, 244, 25);
labelDuration.frame = CGRectMake(252, 5, 40, 20);
}
When I had something to add to a cell that is dynamically located like labelDesc is, I had to totally pull it out of my custom cells class and put it all in cellForRowAtIndexPath (so I would have something like labelDesc = [[UILabel alloc] initWithFrame... and so on all in cellForRowAtIndexPath, and nothing for it in the initWithStyle).
I don't know why doing it this way is any different than setting the frames in initWithStyle, but it seems to be working for me.

Programmatically created UITableViewCell subclass only working on highlight

I've created a subclass of UITableViewCell but I'm struggling to get it to work properly. If I use UITableViewStyleDefault then the class only works when highlighted. If I use UITableViewStyleValue1 then it mostly works but I'm unable to change label fonts much.
I tried researching but it seems everyone is doing this via a .xib file, but not programmatically.
Implementation file
#import "ASCustomCellWithCount.h"
#implementation ASCustomCellWithCount
#synthesize primaryLabel,secondaryLabel,contentCountImage,contentCount;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
contentCountImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed: #"tableCount.png"] ];
primaryLabel = [[UILabel alloc] init];
primaryLabel.textAlignment = UITextAlignmentLeft;
primaryLabel.textColor = [UIColor blackColor];
primaryLabel.font = [UIFont systemFontOfSize: 20];
primaryLabel.backgroundColor = [UIColor clearColor];
secondaryLabel = [[UILabel alloc] init];
secondaryLabel.textAlignment = UITextAlignmentLeft;
secondaryLabel.textColor = [UIColor blackColor];
secondaryLabel.font = [UIFont systemFontOfSize: 8];
secondaryLabel.backgroundColor = [UIColor clearColor];
contentCount = [[UILabel alloc] init];
contentCount.textAlignment = UITextAlignmentCenter;
contentCount.font = [UIFont boldSystemFontOfSize: 15];
contentCount.textColor = [UIColor whiteColor];
contentCount.shadowColor = [UIColor blackColor];
contentCount.shadowOffset = CGSizeMake(1, 1);
contentCount.backgroundColor = [UIColor clearColor];
[self.contentView addSubview: contentCountImage];
[self.contentView addSubview: primaryLabel];
[self.contentView addSubview: secondaryLabel];
[self.contentView addSubview: contentCount];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
// CGFloat boundsX = contentRect.origin.x;
primaryLabel.frame = CGRectMake(0 ,0, 200, 25);
secondaryLabel.frame = CGRectMake(0, 30, 100, 15);
contentCount.frame = CGRectMake(contentRect.size.width - 48, contentRect.size.height / 2 - 13, 36, 24);
contentCountImage.frame = CGRectMake(contentRect.size.width - 48, contentRect.size.height / 2 - 12, 36, 24);
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc {
[primaryLabel release];
[secondaryLabel release];
[contentCountImage release];
[contentCount release];
}
#end
And then to create the cell I use
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
ASCustomCellWithCount *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ASCustomCellWithCount alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat:#"%#", [tempArray objectAtIndex: indexPath.row]];
cell.contentCount.text = #"49";
return cell;
}
For the sake of completeness, my issue was trying to use the custom cells default cell.textLabel.text rather than my custom cell.primaryLabel.text.
As soon as you use one of the default objects in a cell it reverts to the default cells rather than a subclass.

Custom label background gets covered when cell is selected

I'm having a weird problem with my cells when it gets highlighted.
Just to introduce you better what the problem is, take a look at these two pictures:
This is how the cell looks like when it's not selected (normal state): http://cl.ly/0n193u3U1o403x1s0m3z
This is how the cell looks when it's highlighted (during tap): http://cl.ly/1o2U400D3L0b3n3m1N1J
As you can see, the background of the second label seems to get ignored when the cell is selected.
I don't want this to happen. I just want the 2nd label to stay there and remain as it is.
This is how I create the cells (there are several types each of them using different cell identifier).
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellTableIdentifier] autorelease];
cell.backgroundView = [[[UIView alloc] init] autorelease];
}
switch (indexPath.section) {
...
...
case kTableSectionPending:
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 10, self.tableView.frame.size.width - 20, 30.0)] autorelease];
UILabel *label2 = [[[UILabel alloc] initWithFrame:CGRectMake(10, 50, self.tableView.frame.size.width - 20, 30.0)] autorelease];
label.text = NSLocalizedString(#"IncompletePath", #"");
label.font = [UIFont boldSystemFontOfSize:16];
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.layer.cornerRadius = 10;
FFRoute *lastPoint = ((FFRoute *) [[[FFSQLite sharedSingleton] getRoutesFromItinerary:itinerary] lastObject]);
label2.text = [NSString stringWithFormat:#"%#: %#", NSLocalizedString(#"LastPoint", #""), [self getStringFromTimestampOfFFRoute:lastPoint]];
label2.font = [UIFont systemFontOfSize:15];
label2.textAlignment = UITextAlignmentCenter;
label2.textColor = [UIColor whiteColor];
label2.backgroundColor = [UIColor colorWithRed:68/255.f green:82/255.f blue:124/255.f alpha:1];
label2.layer.cornerRadius = 10;
[label2 setOpaque:YES];
[cell.contentView addSubview:label];
[cell.contentView addSubview:label2];
// Set up background color
UIColor *bgcolor = [UIColor colorWithRed:250/255.f green:212/255.f blue:137/255.f alpha:1];
cell.backgroundView.backgroundColor = bgcolor;
break;
}
I tried to set to true the Opaque property with no luck.
What am I missing? Thank you
When you create the cell, do:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
A cell can be highlighted, selected or both. You might want to customize your drawing so that it draws in a selected state (but draws as usual when only in highlighted state).
In iOS 6, you can use 2 methods in UITableViewDelegate to customise highlighting for the cell, and also its subviews:
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor lightGrayColor]]; // Your highlight color
// Make changes to subviews in cell
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:0.5f animations:^{
[cell setBackgroundColor:[UIColor whiteColor]]; // Your unhighlight
// Revert back changes for subviews
}];
}

how to add more than one image and button in UITableView?

I want to add more than one image in table view.
I can add one image using cell.imageview.image.
but how to add one more image.
And I also want to add buttons in all cells.
How can I do that ?
You should make your own UITableViewCell subclass. There are many tutorials for that:
http://iphone.zcentric.com/2008/08/05/custom-uitableviewcell/
http://www.icodeblog.com/2009/05/24/custom-uitableviewcell-using-interface-builder/
http://www.e-string.com/content/custom-uitableviewcells-interface-builder
Including:
http://stackoverflow.com
http://www.google.com
Make your own UITableViewCell subclass.
Use a UITableView with a custom cell with whatever you want in it, load extra images and labels. To get the custom cell, create an IBOutlet to the cell and use this method.
[[NSBundle mainBundle] loadNibNamed:#"customCellView" owner:self options:nil];
To make a cell, make a new Nib/Xib file which is blank, make files owner the class with the cells, drag a UITableviewcell object out and put whatever objects you want on top of that view, set background as clear color and when you load the nib, enter all info into those images and labels. GL
Here is a block of code I use alot in my apps. Its not the fastest way to implement, but it gives you complete control over how the cell looks and whats in it. Using the code below you can see how my app looks. You have 2 buttons on one cell. They both do something different when pushed, and if the actual CELL is selected I do something else. I removed some of the code because im sure you dont care about what Im doing when the cell is selected, only how to get the buttons on, and know which one is pushed.
-(void)scheduleServiceButtonPressed:(id)sender {
//when the user click the button "service appt" on a table cell, we get the cellRow and use that to identify which car to show
ServiceApptViewController * vc = (ServiceApptViewController *)[[ServiceApptViewController alloc] init];
vc.cameFromGarageSelectionInt = [sender tag]; // here is the cell row that was selected.
[self.navigationController pushViewController:vc animated:YES];
[vc release];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 70;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [app.savedUserVehicleArray count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
cell = [self getCellContentView:CellIdentifier:indexPath.row];
[cell setBackgroundColor:[UIColor redColor]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
NSLog(#"out cells for index");
return cell;
}
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier:(int)cellIndex {
NSLog(#"in content");
vehicleForRow = [app.savedUserVehicleArray objectAtIndex:cellIndex];
//CGRect CellFrame = CGRectMake(0, 0, 300, 60);
CGRect CellFrame = CGRectMake(0, 0, 320, 70);
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
// put a UIView underneath for coloring
UIView * view = [[UIView alloc] initWithFrame:CellFrame];
if ( cellIndex%2 == 0 ){
view.backgroundColor = [UIColor whiteColor];
}else{
//view.backgroundColor = [UIColor colorWithRed:0.98 green:0.92 blue:0.52 alpha:1.0];
view.backgroundColor = [UIColor colorWithRed:.238 green:.238 blue:0.238 alpha:.10];
}
[cell.contentView addSubview:view];
[view release];
if (vehicleForRow.isDefault && [vehicleForRow.isDefault compare:#"YES"]==0) {
//add green check mark if vehicle is default
UIImageView * bgimage3 = [[UIImageView alloc] initWithFrame:CGRectMake(245, 15, 40, 32)];
bgimage3.image = [UIImage imageNamed:#"greenCheckMark.png"];
[cell.contentView addSubview:bgimage3];
[bgimage3 release];
//default vehicle label
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"Default"];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(240, 43, 250, 25); // name
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:12];
lblTemp.textColor = [UIColor blueColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
}
else {
UIImageView * bgimage3 = [[UIImageView alloc] initWithFrame:CGRectMake(250, 15, 30, 24)];
bgimage3.image = [UIImage imageNamed:#"grayCheckMark.png"];
[cell.contentView addSubview:bgimage3];
[bgimage3 release];
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"Set As Default"];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(233, 38, 250, 25); // name
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:8];
lblTemp.textColor = [UIColor grayColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
}
// add service button to each cell
UIImage *image;
schedServiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
image = [UIImage imageNamed:#"tableServiceButton.png"];
[schedServiceButton setBackgroundImage:image forState:UIControlStateNormal];
schedServiceButton.frame = CGRectMake(5, 30, 97, 35);
[schedServiceButton setTag:cellIndex];//this is how we know which cell button was pressed
[schedServiceButton addTarget:self action:#selector(scheduleServiceButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
schedServiceButton.titleLabel.font = [UIFont systemFontOfSize:12];
[schedServiceButton.titleLabel setLineBreakMode:UILineBreakModeCharacterWrap];
[schedServiceButton setTitle:#"Schedule\nService Appt." forState:UIControlStateNormal];
schedServiceButton.titleLabel.textAlignment = UITextAlignmentCenter;
[cell.contentView addSubview:schedServiceButton];
//yes add owners manual button
viewOMButton = [UIButton buttonWithType:UIButtonTypeCustom];
image = [UIImage imageNamed:#"tableOMButton.png"];
[viewOMButton setBackgroundImage:image forState:UIControlStateNormal];
viewOMButton.frame = CGRectMake(105, 30, 97, 35);
[viewOMButton setTag:cellIndex];
[viewOMButton addTarget:self action:#selector(viewOwnersManualButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
viewOMButton.titleLabel.font = [UIFont systemFontOfSize:12];
[viewOMButton.titleLabel setLineBreakMode:UILineBreakModeCharacterWrap];
[viewOMButton setTitle:#"View\nOwner's Manual" forState:UIControlStateNormal];
viewOMButton.titleLabel.textAlignment = UITextAlignmentCenter;
[cell.contentView addSubview:viewOMButton];
//car description label
UILabel *lblTemp;
NSString * z = [NSString stringWithFormat:#"%# %# %#",vehicleForRow.userVehicleYear,vehicleForRow.userVehicleMake,vehicleForRow.userVehicleModel];
NSString * s1 = z;
CGRect Label1Frame = CGRectMake(10, 5, 250, 25); // name
//Initialize Label with tag 1.
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
lblTemp.adjustsFontSizeToFitWidth = TRUE;
lblTemp.text = s1;
lblTemp.font = [UIFont boldSystemFontOfSize:16];
lblTemp.textColor = [UIColor blueColor];
lblTemp.backgroundColor = [UIColor clearColor];
[lblTemp setTextAlignment:UITextAlignmentLeft];
[cell.contentView addSubview:lblTemp];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
}

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 the cells had moved off screen and then came back. Upon some research I found that maybe it had something to do with dequeueReusableCellWithIdentifier: 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 to scroll 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;
}