Why can't I set an image to my UITableViewCell? - ios

I created an option menu using a UITableViewController and can get the labels to set correctly, but not the images.
I tried taking out the switch statement and using an array filled with the correct values based on [indexPath row] and could not get it to work correctly either.
Any ideas?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
}
switch ([indexPath row]) {
case 0:
[[cell imageView] setImage:[UIImage imageNamed:#"42-photos.png"]];
[[cell textLabel] setText:#"Photos"];
break;
case 1:
[[cell imageView] setImage:[UIImage imageNamed:#"280-clapboard.png"]];
[[cell textLabel] setText:#"Videos"];
break;
case 2:
[[cell imageView] setImage:[UIImage imageNamed:#"42-info.png"]];
[[cell textLabel] setText:#"About"];
break;
default:
return cell;
break;
}
return cell;
}

The UITableViewCellStyleValue2 doesn't include the image:
A style for a cell with a label on the left side of the cell with text
that is right-aligned and blue; on the right side of the cell is
another label with smaller text that is left-aligned and black. The
Phone/Contacts application uses cells in this style.
You should use UITableViewCellStyleDefault instead (or design your own cell).

You have not created a custom cell i guess , it's better to have a custom cell if you have so many controls in your UITableViewCell and then accessing the property to the controls you can change the image.you can refer this post of mine.Your style chosen will not support image.

Related

iOS - How to neglect dequed cell after change in UItableView

I have a simple tableView in which i change the cell whenever i click it in the function like this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self shuftleCellExpansion:indexPath.row];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
}
Second Functions:
-(BOOL) shuftleCellExpansion:(int) indexP
{
if([opendedCells containsIndex:indexP])
{
[opendedCells removeIndex:indexP];
return YES;
}
else
{
[opendedCells addIndex:indexP];
return YES;
}
}
Cell for index Function:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self isCellInExpandedList:indexPath.row])
{
NSLog(#"Cell is in Expanded State %hhd for Index Path %ld",[self isCellInExpandedList:indexPath.row], (long)indexPath.row);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"poCell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"poCell"];
cell.backgroundColor = [UIColor blueColor];
}
[[cell textLabel] setText:[searchResults objectAtIndex:indexPath.row]];
[cell imageView].image = [UIImage imageNamed:#"someicon.png"];
return cell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"poCell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"poCell"];
cell.backgroundColor = [UIColor redColor];
}
[[cell textLabel] setText:[searchResults objectAtIndex:indexPath.row]];
return cell;
}
No the issue is that when ever i change a specific cell and then scroll it the cell at after the specific cells (i.e. after total visible cells) i see the same changed cell .
What is the efficient way to get Rid of this?
Every cell which go off the screen goes to reuse pool (mostly all data are erase) and if you scroll back the cell is populated in cellForRowAtIndexPath: method again.
You need to change the data source if you want to keep the changes.
In your didSelectRowAtIndexPath: you need to also make the changes in the array (I assume you use array to read the data from in cellForRowAtIndexPath:) you use in cellForRowAtIndexPath: to populate cell.
Hope this help.
// EXTENDED
To make it work you need to amend shuftleCellExpansion: method. In opendedCells you swap the indexes, I believe it reflect the changes in table view. In the same method you have to reflect the changes for searchResults array as well (swap the object as you did for opendedCells).

UITableView change image on cell select and reset others

I'd like to change a UIImage which is inside a UITableViewCell when the user selects the row. Thats now too dificult. I can do this in didSelectRowAtIndex just fine. However, and heres the problem, I want the other cells (each cell has standard image) to have the standard image again. (If the cells have the standard image again, the selected image should be "marked" (meaning the non-marked image will be replaced by the marked image, which I already have the code for)
See it as a Checkbox that you know from HTML.
Here is my attempt:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView cellForRowAtIndexPath:indexPath];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:YES];
//Little flashing animation
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[UIView animateWithDuration:2.0f animations:^{
} completion:^(BOOL finished) {
;
}];
//Mark the selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
ALog(#"%i", cell.imageView.tag);
ALog(#"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);
UIImageView *iconimgView = (UIImageView *)[[tableView cellForRowAtIndexPath:indexPath] viewWithTag:TAG_IMAGEMARKERCELL];
[iconimgView setImage:[UIImage imageNamed:#"circle-answer-marked.png"]];
//..
}
The UIImageView is defined here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//Add this to cell only once, not everytime a cell is displayed! (Everyhing goes in here)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
[[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
[[cell textLabel] setFont:[UIFont fontWithName:#"PTSans-Regular" size:33 / 2]];
[[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
cell.indentationLevel = cell.indentationLevel + 2;
// //Marker image
imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
imgCell_Marker.image=[UIImage imageNamed:#"circle-answer.png"];
imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
ALog(#"%#", imgCell_Marker);
[cell.contentView addSubview:imgCell_Marker];
}
//..
return cell;
}
Odd thing is, the UIImageViews have a predefined tag but if I want to get my hands on that in the didSelectRowAtIndexPath its always "0". (the default value of the tag)
Thanks in advance.
Use this block of code:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadData];
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"image.png"];
}
At first, you set all of your cells to their default condition, and then you change the image of your current cell.
You have issues on a number of fronts.
First, the information which determines what image should be displayed should be part of your model. So, when a row is selected, set a flag in your model to say that this item is tagged. At the same time, find the other items that are tagged and untag them. Now, reload the rows that have changed. In cellForRowAtIndexPath, update the requested cells to set the standard or the alternative image based on the tag info from the model.
Second, for your use of tag - you are getting mixed up between imgCell_Marker and imageView. When you do:
ALog(#"%i", [[[tableView cellForRowAtIndexPath:indexPath] imageView] tag]);
you are querying the default imageView, so the tag will always be zero. You should be using viewWithTag:TAG_IMAGEMARKERCELL to find the actual image view you want.
From attribute inspector, set accessory as "Check Mark" for your prototypeCell. This would solve your issue. No need to change image or anything. let me know if this is not what you want
Make you life easy. Use UITableViewCell::selectedBackgroundView to pre set the content for selected cellĀ“s.
NOTE: this is perfect in my case, so you probably dont want to use it in your case (or let me explain you why you should when you're in a similar position as me)
The code would look like that now:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
[[cell textLabel] setNumberOfLines:0]; // unlimited number of lines
[[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping];
[[cell textLabel] setFont:[UIFont fontWithName:#"PTSans-Regular" size:33 / 2]];
[[cell textLabel] setTextColor:[self colorFromHexString:COLOR_DEFAULT_TEXT_COLOR]];
cell.indentationLevel = cell.indentationLevel + 2;
//Marker image
imgCell_Marker = [[UIImageView alloc]initWithFrame:CGRectMake(10, 22, 20, 20)];
imgCell_Marker.image=[UIImage imageNamed:#"circle-answer.png"];
imgCell_Marker.tag = TAG_IMAGEMARKERCELL;
[cell.contentView addSubview:imgCell_Marker];
//.. (more data here, just snipped it)
return cell;
}
Here is why I am using this:
I know that my array from where the data for the UITableView comes from is only at top 5 items long. Therefore I can simply delete the if statement in my cellForRowAtIndexPath method of my UITableView. It wont hurt my app (or waste cpu time) because there is so little to do, no know will know.
Still, this solution is kinda ugly. But its okay (I guess) in this case

UITableViewCell detailTextLabel area not allowing selection of cell

Inside a UITableViewCell, the area covered by detailTextLabel doesn't recognise selection of the cell.
The cell style is UITableViewCellStyleSubtitle
The entire bottom area of the cell is not selectable and users are sometimes tapping the cell multiple times before tapping high enough on the cell for it to detect the touch.
I've tried [[myCell detailTextLabel] setUserInteractionEnabled:NO] or setting background colour to clear which has helped in similar cases, what else can I do?
I thought about adding a UILabel as a subview of the cell instead of detailTextLabel which I will try if I can't find the answer here.
EDIT - as requested
Here is the code from cellForRowAtIndexPath
NSString *cellId = #"cell";
locationsCell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(locationsCell == nil) {
locationsCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}
[[locationsCell textLabel] setFont:[UIFont fontWithName:#"Optima-Bold" size:18]];
[[locationsCell textLabel] setText:#"Choose your location"];
[[locationsCell detailTextLabel] setFont:[UIFont fontWithName:#"Optima" size:14]];
[[locationsCell detailTextLabel] setText:#"Tap to select"];
[[locationsCell detailTextLabel] setBackgroundColor:[UIColor clearColor]];
return locationsCell;
EDIT
Sorry I've messed up. I had set a footer view for another table and it has added a clear footer view that made the cell un-selectable instead of adding a conditional for the two tables. I removed the footer and it's working.
Friend I tried myself what you are saying but for me it is working.
I tried simple code like this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *TableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:TableIdentifier];
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.detailTextLabel.text=[NSString stringWithFormat:#"subtitle area text working %# %d",[array objectAtIndex:indexPath.row],indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"indexpath row %d",indexPath.row);
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"working" message:#"yes" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}

tableview with checkmark and detail disclosure together

I'm making a tableview with multiple row selected option. So, I used the checkmark accessory type action. I also require to edit/rename the text in the selected row.
Basically, I need to put checkmark (checkbox) on the left side and detail disclosure on the right side of the cell, both functional.
Below code is for checkmark that i have, currently checkmark appears on the right side of the cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
TSIPAppDelegate *appDelegate = (TSIPAppDelegate *)[[UIApplication sharedApplication]delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
if (cell.accessoryType==UITableViewCellAccessoryNone)
{
cell.accessoryType=UITableViewCellAccessoryCheckmark;
appDelegate.selectedFile = cellText;
if (prevSP!=indexPath.row) {
cell=[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:prevSP inSection:0]];
cell.accessoryType=UITableViewCellAccessoryNone;
prevSP=indexPath.row;
}
}
else if (prevSP!=indexPath.row){
cell.accessoryType=UITableViewCellAccessoryNone;
}
}
Any suggestions, please?
When a row selected, checkmark should be enabled/disabled AND disclosure button selected, it should open a new view for editing the selected row.
accessoryType type is of enum UITableViewCellAccessoryType, by definition it will not accept multiple values as it not bitwise enum. So, you have to choose one and mimic the other by custom code.
I'd recommend using the UITableViewCellAccessoryCheckmark accessory type on the tableview and adding a "Detail Disclosure" button to the cell. Unfortunately you can't do exactly what you're looking for, but this is the cleanest alternative approach that I've found.
This is sample code which i have used in one of my app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text=[NSString stringWithFormat:#"%#",[cellarray objectAtIndex:indexPath.row]];
cell.textLabel.textColor=[UIColor blackColor] ;
cell.textLabel.tag=indexPath.row;
cell.textLabel.font=[UIFont fontWithName:#"HelveticaNeue-Bold" size:15];
// cell.textLabel.highlightedTextColor=[UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] ;
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
UIImageView *ima=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"tick.png"]];
ima.frame=CGRectMake(280, 15, 14, 14);
ima.autoresizingMask=UIViewAutoresizingFlexibleLeftMargin |UIViewAutoresizingFlexibleRightMargin;
int row = [indexPath row];
//cell.accessoryType = (row == selectedRow) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
cell.textLabel.textColor= (row == selectedRow) ? [UIColor colorWithRed:242.0f/255.0f green:104.0f/255.0f blue:42.0f/255.0f alpha:1] : [UIColor blackColor] ;
if (row==selectedRow) {
[cell.contentView addSubview:ima];
}
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Background.png"]];
[tempImageView setFrame:tableView.frame];
tableView.backgroundView = tempImageView;
[tempImageView release];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedRow = [indexPath row]; // selected row is of type int declared in .h
[tableView reloadData];
}
This code will have only one checkmark in entire tableView.. You can modify it to have multiple checkmark in that
Hope this helps !!!

xCode 4.2 Assigning a UISwitch to one row of one section produces odd behaviors... IOS

I'm making a settings page, and want the very first row of the first section to have a UISwitch. I've achieved this using the following code:
// 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] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
if (indexPath.section == 0){
[[cell textLabel] setText:[table1labels objectAtIndex:indexPath.row]];
if (indexPath.row == 0 && indexPath.section == 0){
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
}else{
[[cell detailTextLabel] setText:#"test"];
}
}else{
[[cell textLabel] setText:[table2labels objectAtIndex:indexPath.row]];
[[cell detailTextLabel] setText:#"test"];
}
return cell;
}
When the page loads, the first row in the first section has a UISwitch, and all others say "test". However, when I scroll on the page, more UISwitches appear randomly. They do not replace the text "test", but just push it to the left. It does not happen on every one of them. Just randomly when a cell leaves the view and comes back into the view. Can anyone tell me how to fix this?
I've only tested it on the 5.1 simulator. Not on an actual device yet. Could this just be a simulator issue?
You keep reusing the very same cell, that is the important part of your issue.
Now assume a cell that was initially used for your UISwitch is reused for an index that is not equal to the one you want to show it in. For that case, you will have to manually hide or replace the UISwitch.
As an alternative, I would strongly suggest you to use different cell identifiers for the cells that actually do not look alike.
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier;
if (indexPath.row == 0 && indexPath.section == 0)
{
cellIdentifier = #"CellWithSwitch";
}
else
{
cellIdentifier = #"PlainCell";
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
if (indexPath.section == 0)
{
[[cell textLabel] setText:[table1labels objectAtIndex:indexPath.row]];
if (indexPath.row == 0 && indexPath.section == 0)
{
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
}
else
{
[[cell detailTextLabel] setText:#"test"];
}
}else{
[[cell textLabel] setText:[table2labels objectAtIndex:indexPath.row]];
[[cell detailTextLabel] setText:#"test"];
}
return cell;
}

Resources