0

I have a table view with buttons in each of the cell. Each of the button playing different song for each of the cell and change image to "play" or "pause". But I have a problem, when I tap on two or three of buttons, they changes photo to "pause". It should change photo only on one of them. Check photo: Buttons in cell

There is my code in view controller:

extension BeatPackViewController: UITableViewDataSource, UITableViewDelegate {
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 12
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CustomLoopsCell = beatTableView.dequeueReusableCell(withIdentifier: "firstLoopCell", for: indexPath) as! CustomLoopsCell
        gettingSongName()
        
        cell.loopNameLabel.text = data[indexPath.row].loop_name
        cell.producerLabel.text = data[indexPath.row].producer
        cell.instrumentLabel.text = data[indexPath.row].Instrument
        cell.delegate = self
        cell.selectionStyle = .none
        
        cell.tag = indexPath.row
        if let playingCell = currentPlayingIndex {
            if playingCell == indexPath.row {
                cell.playButtonOutlet.setImage(UIImage(named: "Pause.png"), for:
                                                .normal)
            }
        } else {
            cell.playButtonOutlet.setImage(UIImage(named: "playBtn.png"), for:
                                            .normal)
        }
    //        cell.instrumentLabel.text = data[indexPath.row].loops[indexPath.row].Instrument
    //        cell.producerLabel.text = data[indexPath.row].loops[indexPath.row].producer
    return cell
}
    
    func btnUseTap(cell: CustomLoopsCell) {
        
        let indexPath = self.beatTableView.indexPath(for: cell)
        if currentPlayingIndex == cell.tag {
                audioPlayer.pause()
                currentPlayingIndex = nil
            beatTableView.reloadData()
             } else { //IF PAUSE BUTTON
                playLoop(song_name: songs[cell.tag])
                currentPlayingIndex = cell.tag
                beatTableView.reloadData()
             }
            beatTableView.reloadData()
//        playSong(index: indexPath!.row)
        print("Done")
    }
mozeX
  • 23
  • 7

2 Answers2

0

1)Firstly create empty array of your buttons, for example:

let allButtons: [UIButton] = []

2)When you are creating each cell, add button of that cell to array , Example code:

allButtons.append(yourButton)

3)create function that will mute all buttons and also assigning pause image to them, for example:

    func muteAllButtons() {
    for button in allButtons {
        button.muteThisButton()
        button.setImageToPlay()
    }
}
  1. create function that will handle muting all buttons, and then playing music from selected button, for example:

     func userSelectedButton(at yourSelectedCellIndex: Int) {
     muteAllButtons()
     let currentPlayingButton = allButtons[yourSelectedCellIndex]
     currentPlayingButton.playMusic()
     currentPlayingButton.setImageToPause()
    

    }

  2. when user clicks on selected cell, call userSelected function. For example:

    userSelectedButton(at: yourCellIndex)

Mr.SwiftOak
  • 1,469
  • 3
  • 8
  • 19
  • How to mute all of buttons, also my button is in Custom Cell. – mozeX Jul 26 '21 at 13:56
  • Well, looking at your question for one more time I see you do not have problem with muting buttons, so forget that part and we can focus only on changing pause image. It is better to create UIButton inside your cell, than using whole cell as a button. – Mr.SwiftOak Jul 26 '21 at 14:01
0

Looks like you have problem in your if:

if let playingCell = currentPlayingIndex {
    if playingCell == indexPath.row {
        cell.playButtonOutlet.setImage(UIImage(named: "Pause.png"), for:
                                        .normal)
    }
} else {
    cell.playButtonOutlet.setImage(UIImage(named: "playBtn.png"), for:
                                    .normal)
}

When currentPlayingIndex != nil and playingCell != indexPath.row, it doesn't update the image, so it gets random image from dequeued cell. Change it to:

if let playingCell = currentPlayingIndex, playingCell == indexPath.row {
    cell.playButtonOutlet.setImage(UIImage(named: "Pause.png"), for:
                                    .normal)
} else {
    cell.playButtonOutlet.setImage(UIImage(named: "playBtn.png"), for:
                                    .normal)
}

Also you have redundant reloadDatas here:

if currentPlayingIndex == cell.tag {
    audioPlayer.pause()
    currentPlayingIndex = nil
 beatTableView.reloadData()
 } else { //IF PAUSE BUTTON
    playLoop(song_name: songs[cell.tag])
    currentPlayingIndex = cell.tag
    beatTableView.reloadData()
 }
beatTableView.reloadData()

Just remove both from if/else and left one after the if/else.

Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220
  • Also maybe you know how to do, that when song is already player for 07 sec, the button changed from pause to play button? – mozeX Jul 26 '21 at 14:22
  • @mozeX After 7 seconds of playback it changes to play button? Can't say why, check out where else `currentPlayingIndex` gets modifier and `reloadData` gets called, the code you've posted doesn't seems to have anything related – Phil Dukhov Jul 26 '21 at 14:26
  • I mean, how to detect that when song is end playing, the button will change to "play" – mozeX Jul 26 '21 at 14:37
  • @moreX depends on the player you use. If it's AVAudioPlayer, check out this answer: https://stackoverflow.com/a/27826104/3585796 – Phil Dukhov Jul 26 '21 at 14:49
  • Thank you, will check :) – mozeX Jul 26 '21 at 18:07
  • Hi @mozeX, did my answer solve your question? If so, please accept it. Otherwise, let me know if you have any problems with it. – Phil Dukhov Sep 26 '21 at 10:58