3

The button action is SongsSelectionSongs_Click. When I click this button, the button image changing, the button tap count is getting correct and after selected button images also changing, but when I scroll back and forth in the UITableView the button image seems to be randomly changing.

enter image description here

This is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"SongsTAbleViewCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if(cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"SongsTAbleViewCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];
    }

    btn_songSelect.tag = indexPath.row;
    lbl_songLabel.text = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:@"SongTitle"];
    lbl_artistLabel.text = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:@"SongArtist"];

    return cell;
}

-(IBAction)SongsSelectionSongs_Click:(id)sender
{
    UIButton *button = sender;
    CGPoint correctedPoint = [button convertPoint:button.bounds.origin toView:self.tblv_SongslisttableView];
    NSIndexPath *indexPath = [self.tblv_SongslisttableView indexPathForRowAtPoint:correctedPoint];
    NSLog(@"Button tapped in row %d",indexPath.row);

    SelectedAlbumUrl = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:@"SongUrl"];
    str_songtitle = [[arr_tablVArray objectAtIndex:indexPath.row] objectForKey:@"SongTitle"];

    if ([[button backgroundImageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:@"add.png"]])
    {
        btn_songsShareButton.userInteractionEnabled = YES;
        [btn_songSelect setBackgroundImage:[UIImage imageNamed:@"remove.png"] forState:UIControlStateNormal];
        buttonStatus = buttonStatus +1;
        [btn_songsShareButton setImage:[UIImage imageNamed:@"share selected.png"] forState:UIControlStateNormal];
        }
    else
    {
        [btn_songSelect setBackgroundImage:[UIImage imageNamed:@"add.png"] forState:UIControlStateNormal];
        buttonStatus = 1;
        [btn_songsShareButton setImage:[UIImage imageNamed:@"share unselected.png"] forState:UIControlStateNormal];
    }
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044

3 Answers3

2

You are not doing anything within your cellForRowAtIndexPath to select or deselect image. When you reuse a cell, it doesn't change the state of the cell unless you explicitly tell it to in cellForRow. Therefore, it will either reuse a selected or deselected cell (whatever is the first available reusable cell) and put that on the screen as-is.

To fix this issue, you need logic in your cellForRowAtIndexPath method to either select or deselect the image based on what is appropriate.


In general, if your problem has anything to do with "my cells don't show up right when scrolling" odds are you're not reusing your cells properly.

EDIT: in response to your comment, no, I will not rewrite your code. But I will give you some direction.

I would recommend keeping an additional key/value on your arr_tablVArray that will track whether or not the "share" should be enabled or disabled (I would suggest a bool value). This would make it so that you could check whether or not the "share" is enabled/disabled by checking a bool instead of checking the contents of the button's image in your IBAction method.

This info would now be available in your cellForRowAtIndexPath method as well, and you could check the value for the current record in arr_tablVArray and set your images accordingly just like you set your lbl_songLabel and lbl_artistLabel.

Stonz2
  • 6,306
  • 4
  • 44
  • 64
1

//Try It, it's Working Fine

pragma .h File

NSMutableArray * rowIdArray;

pragma .M File

@synthesize rowIdArray;

- (void)viewDidLoad
  {
    rowIdArray=[[NSMutableArray alloc]init];
  }

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 {
   return 1;
 }

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
   return [NamesArray count];
 }

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
   static NSString *CellIdentifier = @"Cell";
   ViewControllerCell *cell = (ViewControllerCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

   if(cell == nil)
     {
        NSArray *nib;
        nib = [[NSBundle mainBundle] loadNibNamed:@"ViewControllerCell" owner:self options:nil];


        cell = [nib objectAtIndex:0];
     }
// Configure the cell...
  cell.nameslbl.text = [NamesArray objectAtIndex:indexPath.row];

  cell.nameBtn.tag=indexPath.row;
  [cell.nameBtn addTarget:self action:@selector(NamesClick_Tapped:) forControlEvents:UIControlEventTouchUpInside];

   NSString *a=[NSString stringWithFormat:@"%d", indexPath.row];
   NSString *b=[[NSString alloc]init];

  for (int i=0;i<[rowIdArray count];i++)
   {
       b=[rowIdArray  objectAtIndex:i];

        if ([a isEqualToString:b])
         {

           UIImage *buttonImage = [UIImage imageNamed:@"star_selected.png"];
           [cell.nameBtn setBackgroundImage:buttonImage forState:UIControlStateNormal];
          }

       }

      return cell;
}

-(IBAction)NamesClick_Tapped:(id)sender
  {

    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.NameTableView];

    NSIndexPath *indexPath = [self.NameTableView indexPathForRowAtPoint:buttonPosition];

    NSString *rowIdStr = [NSString stringWithFormat:@"%d", indexPath.row];

    if(![rowIdArray containsObject:rowIdStr])
     {

       [rowIdArray addObject:rowIdStr];

     }else{

      [rowIdArray removeObject: rowIdStr];

     }
    [self.NameTableView reloadData];
 }
0

when you reuse a cell where the button has been already set, the same button appears with the previously set image. Instead of creating a new button every time you need a cell, you should just be resetting the state of an existing button. This link might help you.

Community
  • 1
  • 1
Tamil
  • 1,173
  • 1
  • 13
  • 35