UITableview dequeueReusableCellWithIdentifier and scroll-freezing issues - iphone

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;
}

Related

UILabel in Table View - the right way?

I was trying to implement a UILabel into a cell and what I get is overlapping of some values when I scroll the table up and down a couple of times. I work with ARC so there is no release when I want, so my question is : What's the right way of implementing a Label into a tableView cell?
Here is how it looks
- (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];
}
// Configure the cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.textColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1];
cell.textLabel.highlightedTextColor = [UIColor colorWithRed:0.753 green:0.651 blue:0.1569 alpha:1];
UILabel *cellLabelS1 = [[UILabel alloc] initWithFrame:CGRectMake(250, 0, cell.frame.size.width, cell.frame.size.height)];
cellLabelS1.backgroundColor = [UIColor clearColor];
cellLabelS1.font = [UIFont boldSystemFontOfSize:16];
[cellLabelS1 setTextColor:[UIColor whiteColor]];
[cellLabelS1 setText:temperatureString];
temperatureString = nil;
[cell addSubview:cellLabelS1];
[[cell imageView]setImage:[UIImage imageNamed:imageFromCodeDay1]];
[[cell textLabel]setText:cityString];
return cell;
}
You should add a label to the cell only if you don't have one.If you reuse the cells on the second pass you add it again.
So my advice is to set a tag to the label and try to see if the cell contentView bass already the label. If not create and add it.
UILabel *myLabel = (UILabel *)[cell.contentView viewWithTag:2002];
if(!myLabel){
myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 22)];
myLabel.tag = 2002;
[cell.contentView addSubview:myLabel];
}
myLabel.text = #"my new text";
- (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];
UILabel *cellLabelS1 = [[UILabel alloc] initWithFrame:CGRectMake(250, 0,cell.frame.size.width, cell.frame.size.height)];
cellLabelS1.backgroundColor = [UIColor clearColor];
cellLabelS1.tag = 200;
cellLabelS1.font = [UIFont boldSystemFontOfSize:16];
[cellLabelS1 setTextColor:[UIColor whiteColor]];
[cell addSubview:cellLabelS1];
}
// Configure the cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.textColor = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1];
cell.textLabel.highlightedTextColor = [UIColor colorWithRed:0.753 green:0.651 blue:0.1569 alpha:1];
UILabel *cellLabelS1 = (UILabel*)[cell viewWithTag:200];
[cellLabelS1 setText:temperatureString];
temperatureString = nil;
[[cell imageView]setImage:[UIImage imageNamed:imageFromCodeDay1]];
[[cell textLabel]setText:cityString];
return cell;
}
may this will help you....
Your problem is in these lines:
UILabel *cellLabelS1 = [[UILabel alloc] initWithFrame:CGRectMake(250, 0, cell.frame.size.width, cell.frame.size.height)];
cellLabelS1.backgroundColor = [UIColor clearColor];
cellLabelS1.font = [UIFont boldSystemFontOfSize:16];
[cellLabelS1 setTextColor:[UIColor whiteColor]];
When you get a reused cell back from the table view, it already hass this label in it. What you can do to avoid adding duplicate labels is add it only if you need to allocate a new cell. However, this can make retrieving the label back from a reused cell quite complicated.
I would personally suggest creating a custom UITableViewCell in interface builder, and creating a custom UITableViewCell subclass that has a UILabel property.

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
}];
}

Scrollable table having a redraw issue. Doesnt seem to be clearing

I have a scrollable table.
In each cell I draw 3 UILabels. The first few cells draw ok. But as I scroll down the table the UILabels seems to be drawing over previous UILabels. Its like the Labels in the cell have an old label already there that was cleared. I could probably fix this by drawing a background color over the whole cell each redraw, but that still doesn't explain this strange problem and why its happening.
Anybody know why this occurs and what a solution might be?
- (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] autorelease];
}
Match *aMatch = [appDelegate.matchScoresArray objectAtIndex:indexPath.row];
UILabel * teamName1Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, 100, 20)];
teamName1Label.textAlignment = UITextAlignmentCenter;
teamName1Label.textColor = [UIColor redColor];
teamName1Label.backgroundColor = [UIColor clearColor];
teamName1Label.text = aMatch.teamName1;
[cell addSubview:teamName1Label];
UILabel *teamVersusLabel = [[UILabel alloc]initWithFrame:CGRectMake(115,5, 40, 20)];
teamVersusLabel.textAlignment = UITextAlignmentCenter;
teamVersusLabel.textColor = [UIColor redColor];
teamVersusLabel.backgroundColor = [UIColor clearColor];
teamVersusLabel.text = #"V";
[cell addSubview:teamVersusLabel];
UILabel *teamName2Label = [[UILabel alloc]initWithFrame:CGRectMake(155,5, 100, 20)];
teamName2Label.textAlignment = UITextAlignmentCenter;
teamName2Label.textColor = [UIColor redColor];
teamName2Label.backgroundColor = [UIColor clearColor];
teamName2Label.text = aMatch.teamName2;
[cell addSubview:teamName2Label];
return cell;
}
Many Thanks
-Code
I think the best solution for this problem is to define these labels in the
-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier withIndexPath:(NSIndexPath *)indexPath method
-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier withIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]autorelease];
UILabel * teamName1Label = [[UILabel alloc]initWithFrame:CGRectMake(5,5, 100, 20)];
teamName1Label.textAlignment = UITextAlignmentCenter;
teamName1Label.textColor = [UIColor redColor];
teamName1Label.backgroundColor = [UIColor clearColor];
teamName1Label.text = aMatch.teamName1;
teamName1Label.tag = 1;
[cell.contentView addSubview:teamName1Label];
[teamName1Label release];
UILabel *teamVersusLabel = [[UILabel alloc]initWithFrame:CGRectMake(115,5, 40, 20)];
teamVersusLabel.textAlignment = UITextAlignmentCenter;
teamVersusLabel.textColor = [UIColor redColor];
teamVersusLabel.backgroundColor = [UIColor clearColor];
teamVersusLabel.text = #"V";
teamVersusLabel.tag = 2;
[cell.contentView addSubview:teamVersusLabel];
[teamVersusLabel release];
UILabel *teamName2Label = [[UILabel alloc]initWithFrame:CGRectMake(155,5, 100, 20)];
teamName2Label.textAlignment = UITextAlignmentCenter;
teamName2Label.textColor = [UIColor redColor];
teamName2Label.backgroundColor = [UIColor clearColor];
teamName2Label.text = aMatch.teamName2;
teamName2Label.tag = 3;
[cell.contentView addSubview:teamName2Label];
[teamName2Label release];
return cell;
}
Now the cellForRowAtIndexPath method will be--
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=nil;
static NSString *Identifier = #"Cell";
cell = [theTableView dequeueReusableCellWithIdentifier:Identifier];
if(cell == nil){
cell = [self reuseTableViewCellWithIdentifier:Identifier withIndexPath:indexPath];
}
Match *aMatch = [appDelegate.matchScoresArray objectAtIndex:indexPath.row];
UILabel *label = (UILabel *)[cell.contentView viewWithTag:1];
label.text = aMatch.teamName1;
label = (UILabel *)[cell.contentView viewWithTag:2];
label.text = #"V";
label = (UILabel *)[cell.contentView viewWithTag:3];
label.text = aMatch.teamName2;
return cell;
}
Just try this code..Hope it helps :)
This is a cell re-use issue. The code is adding the labels to the cell every time cellForRowAtIndexPath is called (even if cell is not nil).
When you scroll, a previous cell that already has the labels is loaded and then the code adds new labels over the old ones.
Only create and add the labels to the cell in the if (cell == nil) section. When creating the labels, set tags on the labels.
Then outside the if, retrieve the labels using their tag using viewWithTag and set their text.

duplicate rows in tableview on uitableviewcell

I have found some posts which are similar to my issue but not quite the same.
In my app the user can navigate between several uitableviews to drill down to the desired result. When a user goes forward, then backward, then forward, etc it is noticeable that the rows are being redrawn/re-written and the text gets bolder and bolder.
I have found that in some of the posts this may relate to the way that I am creating the rows, using a uilable within the cellforrowatindexpath method.
Is there something that I need to do so that the rows are not repopulate/redrawn each time a user goes forward and backward between the tableviews? Do I need to add something to the code below or add something to the viewwillappear method (currently there is a 'reloaddata' in the viewwillappear for the table but doesn't seem to help)?
Here is my code:
- (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.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
UILabel *label = [[[UILabel alloc] init] autorelease];
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:20];
label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
label.text = [mapareaArray objectAtIndex:indexPath.row];
[cell.contentView addSubview:label];
CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
bgView.borderColor = [UIColor clearColor];
bgView.fillColor = [UIColor whiteColor];
bgView.position = CustomCellBackgroundViewPositionSingle;
cell.backgroundView = bgView;
return cell;
}
The problem you are having is due to this line:
[cell.contentView addSubview:label];
You are adding a subview to the table cell whether it's a new cell or not. If it's an old cell (dequeued from the reusable pool), then you will add yet another subview to the cell.
Instead, you should tag the UILabel, and then locate it with the tag to modify the content of that UILabel. Add (and set all of its attributes) and tag the UILabel inside the if( cell == nil ) block:
if(cell == nil) {
// alloc and init the cell view...
UILabel *label = [[[UILabel alloc] init] autorelease];
label.tag = kMyTag; // define kMyTag in your header file using #define
// and other label customizations
[cell.contentView addSubview:label]; // addSubview here and only here
...
}
Then locate it with:
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];
And no need to re-add it as a subview outside of the if(cell == nil) block. The subview is already there (and that's why reusing the cell views are so much more efficient, if you do it correctly, that is ;).
.h file
The 'define' is put after the #import statements at top of header file, and was put as 0 because I don't know how else to define it:
#define kMyTag 0
.m file
I have updated this section as per your comments, but a) the table is not populated, b) when the user has navigated to the next view and goes back to this view it fails with a "unrecognized selector sent to instance", and c) I had to put in the two 'return cell;' entries or it falls over. I think I have things in the wrong order and maybe didn't initialise things properly????
- (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.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *label = [[[UILabel alloc] init] autorelease];
label.tag = kMyTag; // define kMyTag in your header file using #define
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:20];
label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
bgView.borderColor = [UIColor clearColor];
bgView.fillColor = [UIColor whiteColor];
bgView.position = CustomCellBackgroundViewPositionSingle;
cell.backgroundView = bgView;
[cell.contentView addSubview:label]; // addSubview here and only here
return cell;
}
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];
return cell;
}
You should create a subclass for UITableViewCell for that specific cell, then apply the logic to see if you need to add the subview to itself every time. Also, use the UITableviewcell's prepareForReuse and remove any subviews during that time before applying the logic of wether you want to add a UILabel to your Cell.

How to load images into Custom UITableViewCell?

Here's what I need to do:
Load 66px x 66px images into the table cells in the MainViewController table.
each TableCell has a unique image.
But how? Would we use cell.image?
cell.image = [UIImage imageNamed:#"image.png"];
If so, where? Is an if/else statement required?
To load each cell's labels, MainViewController uses an NSDictionary and NSLocalizedString like so:
//cell one
menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(#"PageOneTitle", #""), kTitleKey,
NSLocalizedString(#"PageOneExplain", #""), kExplainKey, nil]];
//cell two
menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(#"PageOneTitle", #""), kTitleKey,
NSLocalizedString(#"PageOneExplain", #""), kExplainKey, nil]];
...
// this is where MainViewController loads the cell content
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = (MyCustomCell*)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[[MyCustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:kCellIdentifier] autorelease];
}
...
// MyCustomCell.m adds the subviews
- (id)initWithFrame:(CGRect)aRect reuseIdentifier:(NSString *)identifier
{
self = [super initWithFrame:aRect reuseIdentifier:identifier];
if (self)
{
// you can do this here specifically or at the table level for all cells
self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Create label views to contain the various pieces of text that make up the cell.
// Add these as subviews.
nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // layoutSubViews will decide the final frame
nameLabel.backgroundColor = [UIColor clearColor];
nameLabel.opaque = NO;
nameLabel.textColor = [UIColor blackColor];
nameLabel.highlightedTextColor = [UIColor whiteColor];
nameLabel.font = [UIFont boldSystemFontOfSize:18];
[self.contentView addSubview:nameLabel];
explainLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // layoutSubViews will decide the final frame
explainLabel.backgroundColor = [UIColor clearColor];
explainLabel.opaque = NO;
explainLabel.textColor = [UIColor grayColor];
explainLabel.highlightedTextColor = [UIColor whiteColor];
explainLabel.font = [UIFont systemFontOfSize:14];
[self.contentView addSubview:explainLabel];
//added to mark where the thumbnail image should go
imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 66, 66)];
[self.contentView addSubview:imageView];
}
return self;
}
If the image is going to be the same for every cell, i.e., it's part of that type of cell, you could load it in MyCustomCell's init, using self.image = [UIImage imageNamed:"blabla"];
Otherwise, if the image will be different for different cells, it would be more logical to put it in tableView:cellForRowAtIndexPath:
Yes, cell.image is deprecated. use imageview.image instead in the default TableViewCell. I am not sure why custom cell was required to do what the standard tableviewcell already does (title, subtitle, and an image using UITableViewStyleSubtitle)
It works now. You were right, Seventoes, about putting it in tableView:cellForRowAtIndexPath:
indexPath.row was what I was I missing. The working result goes like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = (MyCustomCell*)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[[MyCustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:kCellIdentifier] autorelease];
}
if (indexPath.row == 1)
{
cell.image = [UIImage imageNamed:#"foo.png"];
}
else if (indexPath.row == 2)
cell.image = [UIImage imageNamed:#"bar.png"];
}
...
else
{
cell.image = [UIImage imageNamed:#"lorem.png"];
}
return.cell;
}
A better approach then that if-else mess would be to push your images onto a NSMutableArray in the right order, and then just use
cell.image = [myImages objectAtIndex:indexPath.row];