UITableViewCell делегат не работает

-1

условия:

  • Swift 4, Xcode 9.3
  • Цель: iOS 11.3
  • Пользовательский интерфейс выполнен программно
  • Использование ограничений
  • 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)
    }

}

И вот, как я реализовал на своем контроллере View с табличным представлением: 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)!
    }
}

Проблема:

Мне трудно работать с кнопкой, которая будет использоваться в пользовательской ячейке представления таблицы. Мой табличный вид соответствует протоколу, но он не работает.

  • 0
    Вы пробовали установить ограничение высоты и ширины кнопки?
  • 0
    «это не работает» не является достаточным описанием вашей проблемы. Пожалуйста, будьте более конкретны. Каким именно образом ваш опубликованный код не работает? Пожалуйста, отредактируйте ваш вопрос (не оставляйте комментарий) с более подробной информацией о вашей проблеме.
Показать ещё 8 комментариев
Теги:
uitableview

2 ответа

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
    }()
  • 0
    Ты мой друг, спаситель !! Как этот lazy var может работать?
  • 0
    У uicontrols должна быть слабая ссылка на ячейку, поэтому ленивый var выполняет свою работу.
1

У вас не должно быть действий, которые ячейка выполняет внутри ячейки. Ячейки можно повторно использовать, и ячейка, которая была в строке 1, может оказаться в строке 4 в любое время. Вместо вашей процедуры playPressed() используйте традиционный вызов didSelectRowAtIndexPath, который использует IndexPath, а не сама ячейка, чтобы определить действие, которое нужно предпринять.

  • 0
    Похоже, он хочет отделить действие ячейки от действия определенной кнопки внутри ячейки. Ранее я использовал нечто подобное, когда нажатие на текст ячейки немного «расширяет» его, но нажатие кнопки перенаправит на все детали в новом контроллере представления.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню