首页 > 解决方案 > UITableViewCell 委托不起作用

问题描述

条件:

情况:

这是我的自定义单元格:EpisodeCell.swift

import UIKit

protocol EpisodeCellDelegate {
    func didTapPlayButton(url: String)
}

class EpisodeCell: UITableViewCell {

    var delegate: EpisodeCellDelegate?
    var episode: Episode!

    let cellView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor.init(hex: "#EBE4D3")
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    let episodeTitle: UILabel = {
        let label = UILabel()
        label.textColor = .darkGray
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let playButton: UIButton = {
        let btn = UIButton.init(type: .custom)
        btn.setTitle("PLAY", for: .normal)
        btn.setTitleColor(.gray, for: .normal)
        btn.isUserInteractionEnabled = true
        btn.addTarget(self, action: #selector(playPressed), for: .touchUpInside)
        return btn
    }()

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setup()
    }

    private func setup(){
        self.accessoryType = .none

        self.addSubview(cellView)
        cellView.addSubview(episodeTitle)
        cellView.addSubview(playButton)

        cellView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        cellView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        cellView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        cellView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true

        episodeTitle.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 10).isActive = true
        episodeTitle.leadingAnchor.constraint(equalTo: cellView.leadingAnchor, constant: 10).isActive = true
        episodeTitle.trailingAnchor.constraint(equalTo: cellView.trailingAnchor).isActive = true
        episodeTitle.centerYAnchor.constraint(equalTo: cellView.centerYAnchor).isActive = true

        playButton.translatesAutoresizingMaskIntoConstraints = false
        playButton.trailingAnchor.constraint(equalTo: cellView.trailingAnchor, constant: -10).isActive = true
        playButton.centerYAnchor.constraint(equalTo: cellView.centerYAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("initCoder has not been implemented")
    }

    @objc func playPressed() {
        self.delegate?.didTapPlayButton(url: episode.source)
    }

}

以下是我使用 tableview 在 View Controller 上实现的方式:EpisodesViewController.swift

extension EpisodesViewController: EpisodeCellDelegate {
    func didTapPlayButton(url: String) {
        print("WOAH: \(url)")
    }
}

extension EpisodesViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "episodeCell")  as! EpisodeCell

        cell.episode = series.episodes![indexPath.row]

        cell.episodeTitle.text = ep.episodeName
        cell.delegate = self

        return cell
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return (series.episodes?.count)!
    }
}

问题:

我在使用自定义表格视图单元格中要点击的按钮时遇到困难。我的 tableview 符合协议,但它不起作用。

标签: iosswiftuitableview

解决方案


您不应该在单元格内执行单元格执行的操作。单元格可以重复使用,并且第 1 行中的单元格可以随时在第 4 行中结束。代替您的 playPressed() 例程,使用传统的 didSelectRowAtIndexPath 调用,它使用 IndexPath 而不是单元格本身来确定要采取的操作。


推荐阅读