I have a tableview that is made up of custom tableview cells which contain an imageview. In cellForRowAtIndexPath I set the image of each cell. I want the image to change when the cell is selected, so in didSelectRowAtIndexPath I get the cell and change the image, no problems there. However, when I scroll the table (read: table reloads the cells) the new image is no longer present. Also when the cell is no longer selected I want the image to switch back to the original.
I have tried doing the following in cellForRowAtIndexPath:
if(cell.isSelected){
cell.imageview.image = [UIImage ImageNamed: #"selected.png"];
}
else
cell.imageview.image = [UIImage ImageNamed: #"not selected.png"];
I have also tried using the BOOL values cell.highlighted or cell.selected to no avail.
Any thoughts are appreciated.
Try using a class variable selectedCellIndexPath of type NSIndexPath. In didSelectRow... you set it's value, and in the cellForRow... you write:
if([selectedCellIndexPath isEqual:indexPath]){
cell.imageview.image = [UIImage ImageNamed: #"selected.png"];
} else {
cell.imageview.image = [UIImage ImageNamed: #"not selected.png"];
}
Edit:
Or you could simply write:
if([indexPath isEqual:[tableView indexPathForSelectedCell]]){
cell.imageview.image = [UIImage ImageNamed: #"selected.png"];
} else {
cell.imageview.image = [UIImage ImageNamed: #"not selected.png"];
}
but the first solution is a little more efficient.
If you have an array with the Name of the Images it would be the easiest to change the name at the selected index in the array and reload the table... Like This:
myImageArray = [[NSMutableArray alloc] init];
[myImageArray addObject:#"name1.jpg"];
[myImageArray addObject:#"name2.jpg"];
// etc..
And the in the cellForRowAtIndexPath Method:
-(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];
}
[cell.imageView setImage:[UIImage imageNamed:[myImageArray objecAtIndex:indexPath.row]]];
}
In the didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[myImageArray setObject:#"newName.jpg" atIndexedSubscript:indexPath.row];
[tableView reloadData];
}
Related
The question sums it up-- I'm trying to have a box get checked when someone clicks on the UITableViewCell, which involves changing the image in the cell. The table is set up well and works just fine-- it's displaying the information that I want it to, and the cells select like they should. However I can't get the image to change when the method didSelectRowAtIndexPath is called.
Here's what I have so far. I've removed extraneous code (from other tables, etc), but this should be everything that's relevant.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == diabetesVisitTable) {
if (indexPath.section==0) {
cell.textLabel.text = [_microvascularValues objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"Family Med Unchecked Box.jpg"];
}
else if (indexPath.section==1) {
cell.textLabel.text = [_macrovascularValues objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"Family Med Unchecked Box.jpg"];
}
else if (indexPath.section==2) {
cell.textLabel.text = [_bloodSugarValues objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"Family Med Unchecked Box.jpg"];
}
cell.backgroundColor = [UIColor colorWithRed:0.75 green:0.52 blue:0.53 alpha:1.0];
self.diabetesVisitTable.backgroundColor = [UIColor colorWithRed:0.75 green:0.52 blue:0.53 alpha:1.0];
return cell;
}
else return 0;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.imageView.image = [UIImage imageNamed:#"Family Med Checked Box.jpg"];
}
In your tableView:didSelectRowAtIndexPath: implementation, you're asking the table view for a new cell to configure with dequeueReusableCellWithIdentifier:. You want to fetch the actual cell used for that indexPath so you can update it directly:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"Family Med Checked Box.jpg"];
}
You'll also need to update the data source for the table view somehow to record the fact that one of the rows is selected, and update tableView:cellForRowAtIndexPath: to set the checked image if the data source indicates that the row is selected. If you don't do those steps, the cell will appear unselected when it refreshes.
UITableViewDelegate has 3 methods to handle cell highlighting:
- tableView:shouldHighlightRowAtIndexPath:
- tableView:didHighlightRowAtIndexPath:
- tableView:didUnhighlightRowAtIndexPath:
Try like this :
- (BOOL)tableView:(UITableView*)tableView shouldHighlightRowAtIndexPath:(NSIndexPath*)indexPath
{
return YES;
}
- (void)tableView:(UITableView*)tableView didHighlightRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"Highlightimage"];
}
- (void)tableView:(UITableView*)tableView didUnhighlightRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"image"];
}
You're trying to update the cell at the didSelectRowAtIndexPath function which returns void. So it will not update the tableview.
You should take the indexpath.row value from the diddSelectRowAtIndexPath and pass it to the cellForRowAtIndexPath. if they're matching, update the cell, it will work.
Also make sure you add a beginUpdate and endUpdate to reflect the table value reload
I have UIImageView in custom cell in UITableView and in want to change that image in didSelectRowAtIndexPath
It's working with UIImageView outside the UITableView, but not working inside it.
I am using this code..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *string = [[self.itemsInTable objectAtIndex:indexPath.row] objectForKey:#"Name"];
ExpandCell *cell = [self.menuTableView dequeueReusableCellWithIdentifier:#"Cell"];
UIImage *image;
if ([string isEqualToString:#"News"]) {
if ([[self.viewImage image] isEqual:[UIImage imageNamed:#"down-arrow.png"]]) {
NSLog(#"down");
image = [UIImage imageNamed:#"up-arrow.png"];
} else {
NSLog(#"up");
image = [UIImage imageNamed:#"down-arrow.png"];
}
cell.imgExpand.image = image;
self.viewImage.image = image;
}
}
How can I fix that?
First assign a tag number to your UIImageView (say 10).
Then write this code in your didSelectRowAtIndexPath method
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIImageView *yourImageView = (UIImageView*)[cell viewWithTag:10];//Replace yourImageView with the name of your UIImageView on custom cell
//--------- Your code ------
NSString *str = [[self.itemsInTable objectAtIndex:indexPath.row] objectForKey:#"Name"];
UIImage *image;
if ([str isEqualToString:#"News"])
{
if ([[self.viewImage image] isEqual:[UIImage imageNamed:#"down-arrow.png"]])
{
NSLog(#"down");
image = [UIImage imageNamed:#"up-arrow.png"];
}
else {
NSLog(#"up");
image = [UIImage imageNamed:#"down-arrow.png"];
}
[yourImageView setImage:image];
[self.viewImage setImage:image];
}
I think this will resolve your problem.
The following line creates a new cell:
ExpandCell *cell = [self.menuTableView dequeueReusableCellWithIdentifier:#"Cell"];
Change it to:
ExpandCell *cell = [tableView cellForRowAtIndexPath:indexPath];
This will give you the currently visible cell you just selected.
Add this command [tableView deselectRowAtIndexPath:indexPath animated:YES]; at the end of didSelectRowAtIndexPath
After you set a new image,you can use function:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
reload the cell you changed.
Is it possible to update the cell imageView in an iOS UITableView by tag? I appreciate other methods are available but I would like to use tags if possible.
I set the image by:
cell.imageView.image = [UIImage imageNamed:#"dinner.png"];
And in another method I can get the cell by (Tags are always unique):
NSInteger the_tag = ((UIView*)sender).tag;
UITableViewCell *updateCell = (UITableViewCell*)[tableView viewWithTag:the_tag];
Is it possible to update the cell with this method? This does not work:
updateCell.imageView.image = [UIImage imageNamed:#"lunch.png"];
EDIT:
On reflection, the tags are bad method to use. You can use (Which will give you the row and the section if you have a sectioned table):
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
NSLog(#"Tapped Row %#", indexPath);
UITableViewCell *cell = [self->tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"lunch.png"];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell*)[tblView1 cellForRowAtIndexPath:indexPath.row];
UIImageView *imageView = cell.imageView;//CustomCell you have imageView as #propertyVariable..
imageView.image = [UIImage imageNamed:#"image.png"];
}
I hope it will be helpful for you...
try calling [updateCell setNeedsLayout] or [updateCell.imageView setNeedsLayout]
Thank you for all the answers. On reflection, I feel tags are a bad method to use. I have updated my original post with what I feel is a better solution.
- (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];
cell.tag = indexPath.row;
cell.imageView.image = [UIImage imageNamed:#"icon.png"];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int tag = 2;//this is same at table cell row number.
UITableViewCell *cell = (UITableViewCell*)[tableView viewWithTag:tag];
cell.imageView.image = [UIImage imageNamed:#"image.png"];
}
I have a Gallery Page where I want to have 12 unique CollectionViews that scroll independently. This I can do, but I also want them to scroll vertically as a group. It seems like they need to be in a tableCell. But I can't seem to get this to work. I'm using Story Boards. So the question is how do you put the output of a CollectionView into a tableCell, with each tableRow holding a unique CollectionView.
This the trick to having collectionView swipe horizontal and independent. Each one is "tagged". Now I just need to go vertical too.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath: (NSIndexPath *)indexPath {
NSLog(#">>> Entering %s <<<", __PRETTY_FUNCTION__);
if (cv.tag == 0) {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CELL" forIndexPath:indexPath];
UIImage *theImage = [UIImage imageNamed:[flowerImages objectAtIndex:indexPath.item]];
cell.imageView.image = theImage;
return cell;
} else if (cv.tag == 1) {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CELL2" forIndexPath:indexPath];
UIImage *theImage = [UIImage imageNamed:[carImages objectAtIndex:indexPath.item]];
cell.imageView.image = theImage;
return cell;
} else {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CELL3" forIndexPath:indexPath];
UIImage *theImage = [UIImage imageNamed:[birdImages objectAtIndex:indexPath.item]];
cell.imageView.image = theImage;
return cell;
}
}
Ok, I ended up using Static Table Cells. Worked!
I'm doing the following to set the cell image if a message is unread
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MessageCell"];
Message *m = [self.messages objectAtIndex:indexPath.row];
cell.textLabel.text = m.subject;
NSString *detail = [NSString stringWithFormat:#"%# - %#", m.callbackName, m.dateSent];
cell.detailTextLabel.text = detail;
if([m.messageRead isEqualToString:#"False"])
cell.imageView.image = [UIImage imageNamed:#"new.png"];
return cell;
}
This is correctly showing an image when it's supposed to. If I scroll down however and scroll back up, they all show the image whether it's supposed to or not
Cells are reused. So you need to set each property for every condition.
if([m.messageRead isEqualToString:#"False"])
cell.imageView.image = [UIImage imageNamed:#"new.png"];
else
cell.imageView.image = nil;
Since UITableViewCells are reused, you should set cell.imageView.image to nil in case you do not need image.
if([m.messageRead isEqualToString:#"False"]) {
cell.imageView.image = [UIImage imageNamed:#"new.png"];
} else {
cell.imageView.image = nil;
}