Tengo un controlador de vista que tiene una vista de tabla. Dentro de esa vista de tabla tengo una celda dinámica. Dentro de esa celda tengo una UIView. Dentro de UIView tengo una etiqueta con un reconocedor de tap que se supone que realiza una transición a un controlador de vista diferente. Intenté hacer un delegado entre el controlador de vista poniendo vc.delegate = self en viewdidload, pero no funcionó. También intenté poner la misma línea dentro de cellforrowat, pero todavía no hace nada. ¿Cómo puedo hacer un delegado que se comunique desde mi celular con UIView a este controlador de vista? Además, lo que se comunicará es mi clase UIView y no mi clase celular.

-1
Guest2819 14 ago. 2020 a las 21:21

2 respuestas

La mejor respuesta

Si lo entiendo correctamente. Cree un protocolo de delegado para la vista de su celda, coloque la propiedad de delegado en la celda y páselo a través del método tableView tableView(_:cellForRowAt:) al controlador.

Implementación del protocolo:

protocol MyCellViewDelegate: class {
    func viewDidTap(_ view: MyCellView)
}

Implementación de vista de celda:

class MyCellView: UIView {

    private let tapGesture = UITapGestureRecognizer()
    weak var delegate: MyCellViewDelegate?
        
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        tapGesture.addTarget(self, action: #selector (viewDidTap))
    }
    
    @objc
    func viewDidTap() {
        delegate?.viewDidTap(self)
    }
}

Implementación de celda:

Luego, en la implementación de su celda. Pase la referencia de delegado al MyCellView, que se manejará en el controlador.

class MyCell: UITableViewCell {
    
    private let myContentView = MyCellView()
    
    weak var delegate: MyCellViewDelegate? {
        didSet { myContentView.delegate = delegate }
    }
    
    required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }
}

Entonces debería poder establecer delegado en los métodos de delegado de TableView DataSource.

Implementación del controlador:

extension MyController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Dequeue the cell...
        cell.delegate = self
        return cell
    }
}

Y te obligará a agregar delegados.

extension MyController: MyCellViewDelegate {
    
    func viewDidTap(_ view: MyCellView) {
        // Do some stuff
    }
}

Sin embargo, TableView podría "robar" tu acción de gesto de toque. Quizás, si configura tableView.isUserInteractionEnabled = false, podría funcionar.

1
Lukáš Šanda 14 ago. 2020 a las 19:35

La forma fácil es NotificationCenter. Simplemente publique la notificación y recíbala en ViewController.

Pensé que lograría el uso de delegado también donde necesita pasar la información como se muestra a continuación. Este nivel muy alto en el que supongo que tiene la vista siguiente como una clase separada.

UIView -> [Cell -> TableView] -> UIViewController

También puede utilizar el controlador de finalización.

0
Sandy 14 ago. 2020 a las 18:34