UITableViewCell委托无法正常工作

时间:2018-05-16 13:22:14

标签: ios swift uitableview

条件:

  • Swift 4,Xcode 9.3
  • 目标:iOS 11.3
  • 以编程方式完成UI
  • 使用约束
  • Episode是一个将source保存为字符串
  • 的对象

情况:

这是我的自定义单元格: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)
    }

}

以下是我在ViewView上使用tableview实现的方式: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符合协议,但它不起作用。

2 个答案:

答案 0 :(得分:1)

您应该在tableviewcell内进行延迟初始化以进行控制。下面的代码为我带来了魔力。只需更改代码的以下部分

lazy var cellView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

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

    lazy var 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
    }()

答案 1 :(得分:1)

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