简体   繁体   中英

Problems in setting imageview on a selected cell in tableview in ios

I am having an app in which I am showing some data in my tableview as shown in the ScreenShot1 below.

Screenshot1.

在此处输入图片说明

Now I am having an imageview On my each tableview cell.

If I select any of the cell from tableview, I want an image on that selected cell as shown in screenshot2 below.

Screenshot2.

在此处输入图片说明

Now If I select any other cell form tableview. I want to set my imageview's image only on those selected cells as shown in Screenshot3 below.

在此处输入图片说明

Below is the code I am doing.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }
   lblRecipe  = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];

    lblRecipe.backgroundColor = [UIColor clearColor];

    lblRecipe.font = [UIFont systemFontOfSize:20.0f];
    [cell.contentView addSubview:lblRecipe];
   checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];

    [cell.contentView addSubview:checkedimg];
   lblRecipe.text = [array objectAtIndex:indexPath.row];
  return cell;

}

On Tableview's didselect method, what should i keep to have this kind of a functionality?

I searched a lot and there are lots of questions for this but couldn't find one for this.

So Please help me on this.

Thanks in advance.

You may be better off just subclassing UITableViewCell , as this would let you change the way the cells draw, and add a property or something of the sort to indicate this state.

To create the subclass, create a new file in Xcode, and select UITableViewCell as its superclass.

Then, within that subclass, you could implement a method called setStrikeThrough: like this that you can call on the cell you dequeue from the table:

- (void) setStrikeThrough:(BOOL) striked {
    if(striked) {
        // create image view here and display, if it doesn't exist
    } else {
        // hide image view
    }
}

Then, in the view controller that holds the table, you'd call this in viewDidLoad to register your subclass with the table view:

[_tableView registerClass:[YourAmazingTableCell class] forCellReuseIdentifier:@"AmazingCellSubclass"];

You would then alter your tableView:cellForRowAtIndexPath: to be something like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"AmazingCellSubclass";

    YourAmazingTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[YourAmazingTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // here you would look up if this row should be selected
    [cell setStrikeThrough:YES];

    // Set up the remainder of the cell, again based on the row
    cell.textLabel.text = @"chilli";

    return cell;
}

Try this,

Add a NSMutableArray checkedCellArray, as property and alloc init.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

if (cell == nil) {

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    UILabel *labelRecipe  = [[UILabel alloc] initWithFrame:CGRectMake(50, 5, 600, 32)];

    labelRecipe.backgroundColor = [UIColor clearColor];

    labelRecipe.font = [UIFont systemFontOfSize:20.0f];
    labelRecipe.tag = kRecipeTag;//a tag to label
    [cell.contentView addSubview:labelRecipe];
    UIImageView *checkedimg = [[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
    [checkedimg setImage:[UIImage imageNamed:@"checked.png"];
    checkedimg.tag = kCheckedImageTag;//a tag to imageView
    [cell.contentView addSubview:checkedimg];
    checkedimg.hidden = YES;
}

UILabel *labelRecipe  = (UILabel *)[cell.contentView viewWithTag:kRecipeTag];
UIImageView *checkedimg = (UIImageView *)[cell.contentView viewWithTag:kCheckedImageTag];
if ([self.checkedCellArray containsObject:indexPath]) {
    checkedimg.hidden = NO;
} else {
    checkedimg.hidden = YES;
}
labelRecipe.text = [array objectAtIndex:indexPath.row];
return cell;

}

and in didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if (![self.checkedCellArray containsObject:indexPath]) {
        [self.checkedCellArray addObject:indexPath];
    }
    NSArray* rowsToReload = [NSArray arrayWithObjects:indexPath, nil];
   [UITableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
}

Oky hear you can do like this

just subclass the tableview cell

in CustomCell.h file

 #import <UIKit/UIKit.h>

 @interface CustomCell : UITableViewCell
 @property (nonatomic,retain)UIImageView *dashImageView; //add a property of image view

 @end

in CustomCell.m file

#import "CustomCell.h"

@implementation CustomCell
{
   BOOL isCellSelected; //add this to check
}

@synthesize dashImageView = _dashImageView; //synthesize it

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
   self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
   if (self) {
    // Initialization code
     isCellSelected = NO;//initially set it no
    _dashImageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.bounds.origin.x + 15, self.bounds.origin.y + 10, self.bounds.size.width, 15.0f)];
    _dashImageView.backgroundColor = [UIColor redColor];
    _dashImageView.tag = 12345;
    _dashImageView.hidden = YES;
    [self.contentView addSubview:_dashImageView];

   }
   return self;
 }

 - (void)setSelected:(BOOL)selected animated:(BOOL)animated
 {
     [super setSelected:selected animated:animated];
if(selected)
{
    UIImageView *dashImageVIew = (UIImageView *)[self viewWithTag:12345];
    if(dashImageVIew)
    {
        if(!isCellSelected)
        {
            dashImageVIew.hidden = NO;
            isCellSelected = YES;
        }
        else
        {
            dashImageVIew.hidden = YES;
            isCellSelected = NO;
        }
    }
}


}

EDIT:2 * For selecting both section and row for the table view *

there is no change in the custom cell only change in the controller so that u hav to reflect what changes that u made to tableview cell ie weather u select or deselect since u want select section along with the selected row.(your requirement) there are various way to do that, but i go by using some model object which contains index section and row.

for that u need to create a subclass of NSObject and name it as MySelectedIndex then in in MySelectedIndex.h file

 #import <Foundation/Foundation.h>

 @interface MySelectedIndex : NSObject<NSCoding>//to store and retrieve data like user   defaults, for non-property list objects, confirms to NSCoding protocol
 @property (nonatomic,retain) NSNumber *selectedRow;
 @property (nonatomic,retain) NSNumber *selectedSection;

 - (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection;

 @end

in MySelectedIndex.m file

 #import "MySelectedIndex.h"
 @implementation MySelectedIndex
 @synthesize selectedSection = _selectedSection;
 @synthesize selectedRow = _selectedRow;

 - (id)initWithSelectedRow:(NSNumber *)selRow andSelectedIndex:(NSNumber *)selSection
 {
     self = [super init];
     if(self)
     {
        _selectedRow = selRow;
        _selectedSection = selSection;
     }

     return self;
 }

 - (void)encodeWithCoder:(NSCoder *)aCoder
 {
   [aCoder encodeObject:_selectedRow forKey:@"ROW"];
   [aCoder encodeObject:_selectedSection forKey:@"SECTION"];
 }

 -(id)initWithCoder:(NSCoder *)aDecoder
 {
     self = [super init];
     if(self)
     {
        _selectedRow = [aDecoder decodeObjectForKey:@"ROW"];
        _selectedSection = [aDecoder decodeObjectForKey:@"SECTION"];
     }
     return self;
  }

  @end

now get back to controller where u are using the table

in .m file

    import it #import "CustomCell.h"

and in the method

in viewController.m

     @interface SampleViewController ()<UITableViewDataSource,UITableViewDelegate>
     {
       NSMutableArray *indexes;//to store in defaults
       NSMutableArray *indexesRed;//to red from the defaults

     }

     - (void)viewDidLoad
      {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.

        //...other stuff's

        indexes = [[NSMutableArray alloc]init];//initilise your arrays
        indexesRed = [[NSMutableArray alloc]init];
        //after initilizing your array

         NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"SELECTED_CELLL"];
         if(data != nil)
          {
             indexes = [NSKeyedUnarchiver unarchiveObjectWithData:data];
             [indexes retain];//you hav to retain the objects other wise u will get crash, make sure u will release it by proper memory mabagement (if u are not using ARC)
          }

     }

as u said u are using buttons to pop this viewcontroller so already u know where to place so put this in all the action methods(just replace where u are saving to user defaults ) and also read the comments that i put in the code

//put all these codes where u poping this viewcontroller 
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:indexes];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"SELECTED_CELLL"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.navigationController popViewControllerAnimated:YES]; 

replace the cellForRowAtIndexPath by following code (i added in the below method)

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath
  {
      CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
      if(Cell == nil)
      {
         Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"];
      }

      Cell.textLabel.text = @"Apple";
      NSNumber *rowNum = [NSNumber numberWithInt:indexPath.row];
      NSNumber *secNum = [NSNumber numberWithInt:indexPath.section];
      __block BOOL isImageHidden = YES;
     [indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
       {
          if(obj.selectedRow == rowNum && obj.selectedSection == secNum)
         {
           isImageHidden = NO;
         }
      }];
    Cell.dashImageView.hidden = isImageHidden;
    [Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this

    return Cell;

 }

finally in the method didSelectRowAtIndexPath replace by following method

  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
      NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
      NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];
     if([indexes count] == 0)
     {
        MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
       [indexes addObject:selectedIndx];
    }
   else if ([indexes count] == 1)
   {
     MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
     if(singleIndex.selectedSection == selSection & singleIndex.selectedRow == selRow)
     {
        [indexes removeAllObjects];
     }
     else
    {
        MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
        [indexes addObject:selectedIndx];
    }
  }
  else
 {
     __block BOOL addSelectedRow = NO;
     __block int index = -1;
     [indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)   {
        if(!((obj.selectedRow == selRow) & (obj.selectedSection == selSection)))
        {
           addSelectedRow = YES;
        }
         else
         {
            index = idx;
            addSelectedRow = NO;
            *stop = YES;
        }
      }];
      if(addSelectedRow)
       {
          MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
          [indexes addObject:selectedIndx];
       }
       else
       {
         if(index >= 0)
         {
             [indexes removeObjectAtIndex:index];
         }
       }
    }
   NSLog(@"%@",indexes.description);
   [tableView reloadData];

  }

edit for not able to select more than 13 row's

in viewDidLoad

do like this

  indexes = [[NSMutableArray alloc]init];
  indexesRed = [[NSMutableArray alloc]init];


  NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"SELECTED_CELLL"];
  if(data != nil)
  {
    indexes = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain]; //hear only u retain it
    NSLog(@"%@",indexes.description);//check the description, how many objects are there in the array
    NSLog(@"indexes->%d",[indexes count]);
  }
//[indexes retain];//comment this
} //end of `viewDidLoad`


 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {

    CustomTabedCell *Cell = [tableView dequeueReusableCellWithIdentifier:@"CELL"];
    if(Cell == nil)
    {
        Cell = [[CustomTabedCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CELL"];
    }

      Cell.textLabel.text = @"Apple";
        __block BOOL isImageHidden = YES; //remove that __block qualifier
 //    __block NSInteger currentRow = indexPath.row;
 //    __block NSInteger currentSection = indexPath.section;
 //    [self.indexes enumerateObjectsUsingBlock:^(MySelectedIndex *obj, NSUInteger idx, BOOL *stop)
 //     {
 //         NSInteger rowNum = [obj.selectedRow integerValue];
 //         NSInteger secNum = [obj.selectedSection integerValue];
 //        if(rowNum == currentRow && secNum == currentSection)
 //        {
 //            isImageHidden = NO;
 //        }
 //    }];
   //comment block code and use simple for loop, looping through each obj slightly faster
   for(int k = 0;k < [indexes count];k++)
   {
      MySelectedIndex *seletedIndex = [indexes objectAtIndex:k];
      NSInteger row = [seletedIndex.selectedRow integerValue];
      NSInteger sec = [seletedIndex.selectedSection integerValue];


      if(row == indexPath.row & sec == indexPath.section)
      {
          isImageHidden = NO;
      }
  }


   Cell.dashImageView.hidden = isImageHidden;
   [Cell.contentView bringSubviewToFront:Cell.dashImageView];//as i notised the red dash imageview appers below the text, but in your image it is appearing above the text so put this line to bring the imageview above the text if dont want commnent this
   return Cell;
}



 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{



   NSNumber *selSection = [NSNumber numberWithInt:indexPath.section];
   NSNumber *selRow = [NSNumber numberWithInt:indexPath.row];



   if([indexes count] == 0)
   {
        MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
        [indexes addObject:selectedIndx];
   }
   else if ([indexes count] == 1)
   {
       MySelectedIndex *singleIndex = [indexes objectAtIndex:0];
       NSInteger rowNumInInt = [singleIndex.selectedRow integerValue];
       NSInteger sectionInInt = [singleIndex.selectedSection integerValue];

       if(sectionInInt == indexPath.section & rowNumInInt == indexPath.row)
       {
           [indexes removeAllObjects];
       }
       else
      {
          MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
          [indexes addObject:selectedIndx];
       }
   }
   else
    {
       BOOL addSelectedRow = NO;
       int index = -1;

       for(int j = 0; j < [indexes count];j++)
      {
          MySelectedIndex *selectedObj = [indexes objectAtIndex:j];
          NSInteger rowInt = [selectedObj.selectedRow integerValue];
          NSInteger sectionInt = [selectedObj.selectedSection integerValue];

         if(!(rowInt == indexPath.row && sectionInt == indexPath.section))
         {
            addSelectedRow = YES;
         }
          else
          {
              index = j;
              addSelectedRow = NO;
             // *stop = YES;
          }
        }
       if(addSelectedRow)
       {
          MySelectedIndex *selectedIndx = [[MySelectedIndex alloc]initWithSelectedRow:selRow andSelectedIndex:selSection];
          [indexes addObject:selectedIndx];
       }
       else
       {
          if(index >= 0)
          {
              [indexes removeObjectAtIndex:index];
          }
       }
     }

 // [tableView reloadData];
  NSLog(@"indexes count->%d",[indexes count]);//check each time by selecting and deselectin weateher it is working or not
  [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
 }

thats it simple .. :) hope this helps u .. :)

Try This it work good

#import "ViewController.h"

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
    UITableView *menuTableView;
    NSMutableArray *colorsArray,*tagvalueArray;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
menuTableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 60, 320, 404) style:UITableViewStyleGrouped];
menuTableView.delegate=self;
menuTableView.dataSource=self;
menuTableView.separatorColor=[UIColor grayColor];
[self.view addSubview:menuTableView];
NSArray *serverResponseArray=[[NSArray alloc]initWithObjects:@"red",@"yellow",@"pink",@"none", nil]; // consider this array as the information you receive from DB or server
colorsArray =[[NSMutableArray alloc]init];
tagvalueArray =[[NSMutableArray alloc]init];

for (int i=0; i<serverResponseArray.count; i++) {

    [colorsArray addObject:serverResponseArray[i]];
    [tagvalueArray addObject:@"0"];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return colorsArray.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 40;
}
-(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];
}  
for (UIView *view in cell.contentView.subviews) {
     [view removeFromSuperview];
}
cell.textLabel.text =colorsArray[indexPath.row];
if ([[tagvalueArray objectAtIndex:indexPath.row]intValue]==1) {
    UIImageView *checkedimg=[[UIImageView alloc]initWithFrame:CGRectMake(40, 20, 500, 5)];
    checkedimg.backgroundColor=[UIColor redColor];
    [cell.contentView addSubview:checkedimg];        
    }
 return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%@",colorsArray[indexPath.row]);
    [tagvalueArray replaceObjectAtIndex:indexPath.row withObject:@"1"];
    [menuTableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM