iPhone table view cell style based on cell data - iphone

I'm trying to figure out how to display a particular type of image in a cell based on the text contents of the cell. For example, this method from the tutorial book I am working with will allow me to display the star image for the first 3 cells:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
if (row < 3) {
UIImage *image = [UIImage imageNamed:#"star.png"];
cell.imageView.image = image;
}
cell.textLabel.text = [listData objectAtIndex:row];
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
return cell;
}
Is there any way I can get the actual cell contents here? So For example, if the cell contained the text 'bob', i could display a different image rather than a star?

Well it seems like you can look at your listData object and decide there. So you can try something like this
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
if ([[listData objectAtIndex:row] isEqualToString:#"bob"]) {
UIImage *image = [UIImage imageNamed:#"bob.png"];
cell.imageView.image = image;
}
else if (row < 3) {
UIImage *image = [UIImage imageNamed:#"star.png"];
cell.imageView.image = image;
}
cell.textLabel.text = [listData objectAtIndex:row];
cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
return cell;
}

Maybe you should setup a dictionary that contains the names of the people as the key for the dictionary and the image name as the value. Then you could grab the cell's text and use that as the lookup for the dictionary.

After you set the text:
if([cell.textLabel.text rangeOfString:#"bob"].location != NSNotFound) {
UIImage *image = [UIImage imageNamed:#"bob.png"];
cell.imageView.image = image;
}
else {
UIImage *image = [UIImage imageNamed:#"star.png"];
cell.imageView.image = image;
}

Related

More than one image on UITableView

I need to put two images into a iOS tableview.
I used this code to place the image in a cell:
- (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];
}
UIImage *cellImage = [UIImage imageNamed:#"verde_diversos.png"];
cell.imageView.image = cellImage;
cell.textLabel.text = [self.colorNames objectAtIndex: [indexPath row]];
return cell;
}
Help?
You'll want to create your own UITableViewCell subclass. In its initialiser you would set up two UIImageViews and add them to the contentView as subviews of it. Then in layoutSubviews you would set the frames of the UIImageViews based on how you want them laid out.
- (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];
UIImageView *cellView = [[[UIImageView alloc] initWithFrame:CGRectMake(0,0,100,100)] autorelease];
cellView.tag = 555;
[cell.contentView addSubview:cellView];
}
UIImage *cellImage = [UIImage imageNamed:#"verde_diversos.png"];
cell.imageView.image = cellImage;
cell.textLabel.text = [self.colorNames objectAtIndex: [indexPath row]];
UIImageView *secondImage = [cell.contentView viewWithTag:555];
secondImage.image = [UIImage imageNamed:#"logo.png"];
return cell;
}

The difference between two ways to access UIImageView under UITableViewCell of UITableView

I have a custom tableview to load news through webservice. I change image in each cell in method cellForRowAtIndexPath. After I got the right cell, I can access the image by two ways:
UIImageView *imageView = (UIImageView *)[cell viewWithTag:12];
imageView.image = news.image;
or directly:
cell.imageView.image = news.image;
when I use the second way, some images get into wrong cell while the first way give me a perfect result. It also happend in a callback method iconDownLoadFinsh.
I feel confused about it. Can anyone try to explain it? Please do not hesitate to ask questions. Thanks in advance.
- (void)iconDownLoadFinsh:(NSData *)imageData row:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:12];
imageView.image = [UIImage imageWithData:imageData];
NewsModel *newsModel = [newsArray objectAtIndex:indexPath.row];
newsModel.image = [UIImage imageWithData:imageData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewsCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"NewsTableViewCell" owner:self options:nil];
cell = newsTableViewCell;
newsTableViewCell = nil;
}
// read from newsModel
NewsModel *news = [newsArray objectAtIndex:indexPath.row];
UILabel *label;
label = (UILabel *)[cell viewWithTag:10];
label.text = [NSString stringWithFormat:news.title];
label = (UILabel *)[cell viewWithTag:11];
label.text = [NSString stringWithFormat:news.description];
UIImageView *imageView;
imageView = (UIImageView *)[cell viewWithTag:12];
imageView.image = news.image;
if (news.image == nil)
{
imageView.image = [UIImage imageNamed:IconPlaceHolder];
// if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
IconDownLoader *iconDownLoader = [[IconDownLoader alloc] init];
iconDownLoader.url = news.imageUrl;
iconDownLoader.delegate = self;
iconDownLoader.indexPath = indexPath;
[downloadArray addObject:iconDownLoader];
[iconDownLoader start];
// }
}
return cell;
}
I generally always reset the cell properties in the method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
So I will do the following after getting the cell
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"NewsTableViewCell" owner:self options:nil];
cell = newsTableViewCell;
newsTableViewCell = nil;
}
cell.imageView.image = nil; // Here resetting the imageview's image to nil.
Because you are reusing cells and if you do not clear old data, the cell data may get corrupt.

Adding UIImageView or UIView to the cell of the grouped table

I am having a problem setting a UIImageView or UIView on the cell of the Grouped table on the iPhone.
For this I am using this code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sotreKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
if(indexPath.section == 1 && indexPath.row ==1)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(240, 14, 40, 40)];
imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"Back.png",nil]];
[cell.contentView addSubview:imageView];
[imageView release];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
But it is not placed on the cell . When ever I select the row it will display for that time only, what is the problem?
Does anyone have any idea what the problem is. I think the image is getting overwritten by the cell .
Thanks in advance
try making
cell.accessoryType = UITableViewCellAccessoryNone;
It seems that you are adding image on accessory view.
If yes, you can add cell.accessoryView = imageView;
I do have some ideas of what might be happening.
You are adding an image view to the contentView then you are setting the text of the textLabel which is a part of the contentView and is probably sitting on top of the image. Try this and see if you can at least see your image on the left side.
cell.imageView.image = [UIImage imageNamed:#"Back.png"];
Now when you dequeue cells you need to remember that all the views you added last time you created the cell are still there, so as you scroll you will just be stacking back buttons on top of each other.
Also the following line [tableView deselectRowAtIndexPath:indexPath animated:YES]; is dead code because it occurs after a return statement. You might want to place that in the delegate call – tableView:willDisplayCell:forRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self.tableContents objectForKey:[self.sotreKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
if(indexPath.section == 1 && indexPath.row ==1)
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(240, 14, 40, 40)];
imageView.image = [UIImage imageNamed:#"Back.png"];
[cell.contentView addSubview:imageView];
[imageView release];
}
cell.textLabel.text = [listData objectAtIndex:indexPath.row];
return cell;
}
Make sure that your image is named "Back.png" not "back.png" because the iOS on the phone is key sensitive.

Customizing UITableViewCell

I'm attempting to customize a UITableViewCell to "pretty up" an app, and I'm running into trouble. My code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if ( cell == nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (row == 0 && row == sectionRows - 1) {
rowBackground = [UIImage imageNamed:#"topAndBottomRow.png"];
selectionBackground = [UIImage imageNamed:#"topAndBottomRowSelected.png"];
NSLog(#"topAndBottom");
}
else if ( row == 0 ) {
rowBackground = [UIImage imageNamed:#"topRow.png"];
selectionBackground = [UIImage imageNamed:#"topRowSelected.png"];
NSLog(#"topRow");
}
else if ( row == sectionRows - 1 ) {
rowBackground = [UIImage imageNamed:#"bottomRow.png"];
selectionBackground = [UIImage imageNamed:#"bottomRowSelected.png"];
NSLog(#"bottomRow");
} else {
rowBackground = [UIImage imageNamed:#"middleRow.png"];
selectionBackground = [UIImage imageNamed:#"middleRowSelected.png"];
NSLog(#"middleRow");
}
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
NSString *cellValue = [[listOfItems objectAtIndex:indexPath.row] description];
cell.textLabel.text = cellValue;
return cell;
}
It selects the appropriate image, as shown in the console log, but I have two problems:
1. Setting the (cell.backgroundView).image has no effect
2. Setting the (cell.selectedBackgroundView).image errors out with:
-[UITableViewCellSelectedBackground setImage:]: unrecognized selector sent to instance 0x4b90670
I can find hints about UIView issues with this in google, but haven't found anything about a UITableViewCell. Help?
There's some incompatibilities - there isn't an official background image you can set, IIRC, there's only a background UIView. If you want something that's a UIImageView, you have to do it yourelf.
So, instead, you have to manually set the cell's backgroundView to be a blank UIImageView *when you create the cell, e.g.:
cell.backgroundView = [[[UIImageView alloc] init] autorelease];
...which you can then set images upon.

First row in a UITableview, different from other rows

My UITableView nedd to have, in the first row, an image.
What's the problem? that when the user scrolls down the tableview and, after, he scrolls up, over the image there are the informations of the other rows!
Do you know why?
This is my code (i'm using a UITableViewCell)
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row != 0) {
return 73.0;
}
else {
return 109.0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if (indexPath.row == 0) {
[[NSBundle mainBundle] loadNibNamed:#"customcell_3" owner:self options:NULL];
cell = cellaNib_with_image;
}
else {
[[NSBundle mainBundle] loadNibNamed:#"customcell_2" owner:self options:NULL];
cell = cellaNib;
}
}
if (indexPath.row == 0) {
UIImage *rowBackground;
UIImage *selectionBackground;
rowBackground = [UIImage imageNamed:#"image.png"];
selectionBackground = [UIImage imageNamed:#"image.png"];
cell.backgroundView = [[[UIImageView alloc] init] autorelease];
((UIImageView *)cell.backgroundView).image = rowBackground;
cell.selectedBackgroundView = [[[UIImageView alloc] init] autorelease];
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
}
else {
NSString *elemento = [NSString stringWithFormat:#"%#", [array objectAtIndex:indexPath.row]];
UILabel *testoLabel = (UILabel*)[cell viewWithTag:1];
testoLabel.text = elemento;
//ecc... here a take the other datas
}
return cell;
}
Thanks!
When cells are scrolled, they are reused.
So, first cell may be reused for other cells, and vice versa.
I would use two CellIdentifiers, one for first row, and second for rest of the rows.
If indexPath.row == 0, create/dequeue a cell using CellID1, and configure that and return.
If indexPath.row >1, create/dequeue using CellID2, configure this and return.
If you want to keep using single cellID, then before configuring them, nil/reset all the content first so that previous data are removed.