UITableview更新单个单元格

时间:2019-03-13 22:53:39

标签: ios swift uitableview swift4

每当我轻按播放按钮时,我的tableview自定义单元上就会有一个播放按钮。我希望所选的按钮图像更改为暂停图像。

问题是所有其他按钮的图像正在更新。

因此,所有图像都将变为暂停图像,而不是所选按钮。

我试图点击按钮的indexpath并仅重新加载该行,但这似乎没有什么不同。

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

  let playerCell = tableView.dequeueReusableCell(withIdentifier: "playerCell", for: indexPath) as! PlayerCell
        let item = subcategory?.items?[indexPath.row]
        // Tap gestures extension for cell button action
        playerCell.playPause.addTapGestureRecognizer {
            AudioController.shared.setupPlayer(item: item)
            if let selectedCell = tableView.cellForRow(at: indexPath) as? PlayerCell {
                selectedCell.playPause.setImage(#imageLiteral(resourceName: "pause"), for: .normal)
                tableView.reloadRows(at: [IndexPath(row: indexPath.row, section: 1)], with: .none)
            }
            print("index \(indexPath)")
        }

2 个答案:

答案 0 :(得分:1)

您可以做的是在按钮上添加标签。因此,在创建单元格override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell的方法中,您将一个标记添加到该单元格中代表indexPath的按钮。然后从分配按钮的选择器中,获取要更改的单元格。

例如:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath)

    cell.button.tag = indePath.row
    cell.button.addTarget(self, action: #selector(yourSelector(_sender:)), for: .touchUpInside)
} 

func yourSelector(_sender: UIButton){
    let cell = tableView.cellForRow(at: IndexPath(row: sender.tag, section: 0)) as! YourCellType

    // Change the image, play/pause audio for that cell
}

答案 1 :(得分:0)

点击单元格中的按钮时,不会触发tableView(_:didSelectRowAt:),因此建议您使用delegate来检测按钮的动作。

您需要继续跟踪单元格按钮状态的变化。


例如:

PlayCell.swift

protocol PlayCellDelegate: class {
    func playCellPlayButtonDidPress(at indexPath: IndexPath)
}    
class PlayerCell: UITableViewCell {
    let playButton: UIButton = {
        let button = UIButton()
        button.addTarget(self, action: #selector(playButtonPressed(_:)), for: .touchUpInside)
        return button
    }()

    weak var delegate: PlayCellDelegate?
    var item: MyItem? {
        didSet {
            if item?.status == .paused {
                // set pause image for playButton here
            } else if item?.status == .playing {
                // set play image for playButton here
            }
        }
    }
    var indexPath: IndexPath?
    @objc func playButtonPressed(_ sender: UIButton) {
        guard let indexPath = self.indexPath else { return }
        delegate?.playCellPlayButtonDidPress(at: indexPath)
    }
}


Model.swift

struct Subcategory {
    // ...
    var items: [MyItem]?
}
struct MyItem {
    // ...
    var status: Status.stop
    enum Status {
        case playing, paused, stopped // etc..
    }
}


TableViewController.swift

class TableViewController: UITableViewController, PlayCellDelegate {
    private var subcategory: Subcategory?
    private let cellId = "Cell"        
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? PlayerCell {
            cell.delegate = self
            cell.item = subcategory?.items?[indexPath.row]
            cell.indexPath = indexPath
            return cell
        }
        return UITableViewCell()
    }

    func playCellPlayButtonDidPress(at indexPath: IndexPath) {
        // you only need to change model here, and reloadRows will update the cell.
        if subcategory?.items?[indexPath.row].status == .play {
            subcategory?.items?[indexPath.row].status = .pause
        } // other logic..
        tableView.reloadRows(at: [indexPath], with: .none)
    }
}

希望有帮助!