Search code examples
iphonecocoa-touchuitableviewuibuttondidselectrowatindexpath

Change the image of a specific button pressed in a UITableview


I have a dynamic tableview which has a prototype cell with a button that, when pressed, plays a song.

I'd like for the background image on the button to change to a "stop" icon when the user presses the button to play the song, and for it to change to a "play" icon when the user presses it once again to stop the song.

To accomplish this I've been trying to use: [self.beatPlayButton setBackgroundImage:[UIImageimageNamed:@"play.png"]forState:UIControlStateNormal];

My issue is that I haven't figured out how to change only the button in the row that is being pressed since I'm using prototype cells. I've been hoping to find a method like didSelectObjectAtRow:atIndexPath: because didSelectRowAtIndexPath: will fire when the row is pressed, but not a button on it (unless I'm mistaken). Maybe I should be using a tag? I'm not sure. Any pointers would be greatly appreciated.

EDIT: My code is outside of didSelectRowAtIndexPath.

Here is sample code -

- (IBAction)playStopBeat:(UIButton*)sender event:(id)event {
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
    if([self.audioPlayer isPlaying])
    {
        [self.beatPlayButton setBackgroundImage:[UIImage imageNamed:@"play.png"]forState:UIControlStateNormal];
        [self.audioPlayer stop];
        self.isPlaying = NO;
        self.audioPlayer = nil;
    }
    else {

        if (indexPath.row == 0) {
            [self.beatPlayButton setImage:[UIImage imageNamed:@"stop.png"] forState: UIControlStateNormal];
        }
        else if (indexPath.row == 1){
            [self.beatPlayButton setBackgroundImage:[UIImage imageNamed:@"stop.png"]forState:UIControlStateNormal];
        }
        else if (indexPath.row == 2){
...
//code to play song

Solution

  • Use tags, like you suggested. In your cellForRowAtIndexPath method give each cell a tag:

    cell.tag = indexPath.row;
    

    also set each target on the cells:

    [cell.playButton addTarget:self action:@selector(play:)forControlEvents:UIControlEventTouchUpInside];
    

    Then in your play method, use your tag for your array or w/e:

    - (IBAction)play:sender
    {
         UITableViewCell *cell = (UITableViewCell *)sender;
         NSLog(@"tag = %d", cell.tag);
    
         if(tag == 0)
         {
              //you could also use a switch statement 
         } else if(tag == 1) {
    
         }
    }
    

    ::EDIT:: (answer to comment)

    To disable the other buttons, in your play method:

    - (IBAction)play:sender
    {
         .........
         ....other code....
    
         UITableViewCell *cell = (UITableViewCell *)sender;
    
         for(int i = 0; i < [dataArray count]; i++)
         {
            UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
    
            if(tempCell.tag != cell.tag)
            {
    
                [cell.playButton setEnabled:NO];
            }
         }
    }
    

    In doing this though, after the song is done playing you must set them all back to enabled. This would be done in the MediaPlayers delegate method: didFinishPlaying.