ios: interactúa con el botón en UICollectionViewCell a través del controlador de vista principal

CorePress2024-01-25  14

Estoy creando una aplicación que permite al usuario "fijar" ciertos elementos en una vista de colección que he implementado en mi clase ViewController de inicio. Para anclar un elemento, el usuario debe acceder a un botón que forma parte de mi clase WordCell (UICollectionViewCell). Sin embargo, cuando intento presionar el botón desde mi controlador de vista de inicio, no sucede nada.

Aquí está todo el código y capturas de pantalla relevantes:

La estrella en el lado derecho es el botón dentro de CollectionViewCell que quiero que el usuario pueda presionar en la vista de inicio.

A continuación se muestra todo el código relevante de mi clase ViewController. Estoy usando un delegado para pasar la celda que se presionó en mi ViewController de clase local. También planeo pasar más datos de un lado a otro entre la celda (UICollectionCellView) y ViewController en el futuro.

extension ViewController: UICollectionViewDataSource{
//......
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let wordCell = collectionView.dequeueReusableCell(withReuseIdentifier: wordCellReuseID, for: indexPath) as! WordCell
        
        wordCell.delegate = self
        
        wordCell.configure(word: tempWords[indexPath.item])
        return wordCell
    }
//......
}

extension ViewController: WordCellDelegate{
    func star(wasPressedOnCell: WordCell){
        print("touched")
        
        if(wasPressedOnCell.isStarred){ //if the button has already been starred, unstar it
            wasPressedOnCell.starButton.setImage(UIImage(named: "unfilled_star.png"), for: .normal)
            wasPressedOnCell.isStarred = false
        }
        
        else{ //else, star the button
            wasPressedOnCell.starButton.setImage(UIImage(named: "filled_star.png"), for: .normal)
            wasPressedOnCell.isStarred = true
        }
    }
}

Aquí hay código relevante en mi clase que se ajusta a UICollectionCellView:

//delegate setup for home class
protocol WordCellDelegate: class{
    func star(wasPressedOnCell cell: WordCell) //parameter: cell that was pressed
}

//........

//button setup
starButton = UIButton()
        starButton.setImage(UIImage(named: "unfilled_star.png"), for: .normal)
        starButton.translatesAutoresizingMaskIntoConstraints = false
        starButton.addTarget(self, action: #selector(starred), for: .touchUpInside)
        contentView.addSubview(starButton)

//......

//button objective function
@objc func starred(){
        print("touched")
        
        delegate?.star(wasPressedOnCell: self)
        
        //starredTapAction?() //chained back to main view controller
    }

Sin embargo, cuando intento presionar la estrella en la pantalla de mi controlador de vista de inicio, no se llama a la función objc dentro de mi clase UICollectionCellView. Leí en publicaciones anteriores que esto probablemente se debe a una jerarquía de clases y qué vista controla qué objetos, pero aún no he podido encontrar una solución a este problema. No estoy seguro de qué es necesario cambiar para poder presionar el botón dentro de la celda de la colección en la vista de la colección.

¡Avíseme si necesita más información y gracias por leer esta publicación!

1

Su código parece correcto y debería funcionar. Lo más probable es que el problema esté en la clase collectionView Cell, si el método starred() no se activa. Utilice la jerarquía de depuración para comprobar si el botón está en la parte superior y si no hay otra vista encima, lo que impide el evento .touchUpInside.

Amais Sheikh

28/03/2021 a las 15:06

¡Gracias! Creo que ese es el caso, la vista de colección.está en la parte superior del botón (dentro de la vista de celda). ¿Hay alguna forma de solucionar este problema y permitir que el botón detecte el evento .touchUpInside?

-rjc810

28/03/2021 a las 15:18

La vista de colección no puede estar encima de un botón si el botón está dentro de la clase de celda. La vista de colección tiene celdas, que tienen botones dentro de su vista de contenido, que se encuentran automáticamente en la parte superior. ¿Podrías compartir la clase de celda de vista de tu colección completa para obtener más referencias?

Amais Sheikh

28/03/2021 a las 19:11



------------------------------------

Desactive la selección de celdas de la vista UIcollection y el evento de toque de botón se activará, básicamente en un momento en el que puede usar la vista de colección para seleccionar el método o el método de acción del botón

2

Hola, ¡gracias por tu respuesta! Solo tengo los métodos numberOfItemsInSection y cellForItemAt dentro de mi extensión UICollectionViewDataSource, no didSelectRowAt. ¿Cómo desactivo la selección de celdas?

&Dakota del Norteceniza; rjc810

28/03/2021 a las 17:52

1

Consulte esta pregunta "stackoverflow.com/questions/40988992/…"

-ami solani

28/03/2021 a las 18:05



------------------------------------

Tuve exactamente el mismo problema hace menos de 2 semanas; Todavía no estoy seguro de la causa raíz, pero conozco la solución.

Mover esta línea -- starButton.addTarget(self, acción: #selector(protagonizado), para: .touchUpInside)

dentro de tu celdamétodo de configuración - WordCell.configure (palabra: )

Añadir -- starButton.isEnabled = verdadero starButton.isUserInteractionEnabled = verdadero debajo de tu - //configuración del botón sólo si el toque no se registra (es decir, si no puedes ver el botón cuando se toca)

En realidad se trata de configurar el destino del botón en cellForItemAt(); eso funcionará.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare