¿Es posible que un UIButton (o cualquier otro control para el caso) reciba eventos táctiles cuando el marco del UIButton se encuentra fuera del marco de su padre? Porque cuando intento esto, parece que mi UIButton no puede recibir ningún evento. ¿Cómo soluciono esto?
92
Respuestas:
Si. Puede anular el
hitTest:withEvent:
método para devolver una vista para un conjunto de puntos más grande que el que contiene esa vista. Consulte la referencia de clase de UIView .Editar: Ejemplo:
Edición 2: (Después de la aclaración :) Para asegurarse de que el botón se trate como si estuviera dentro de los límites del padre, debe anular
pointInside:withEvent:
en el padre para incluir el marco del botón.Tenga en cuenta que el código que está ahí para anular pointInside no es del todo correcto. Como Summon explica a continuación, haz esto:
Tenga en cuenta que es muy probable que lo haga
self.oversizeButton
como IBOutlet en esta subclase de UIView; luego puede arrastrar el "botón de gran tamaño" en cuestión, a la vista especial en cuestión. (O, si por alguna razón estuvieras haciendo esto mucho en un proyecto, tendrías una subclase especial de UIButton, y podrías buscar esas clases en tu lista de subvista). Espero que te ayude.fuente
pointInside:withEvent:
para incluir el marco del botón. Agregaré un código de muestra a mi respuesta anterior.hitTest:withEvent:
y elpointInside:withEvent:
área no se me llama cuando presiono un botón que se encuentra fuera de los límites de los padres. ¿Qué puede estar mal?@jnic, estoy trabajando en iOS SDK 5.0 y para que su código funcione correctamente tuve que hacer esto:
La vista de contenedor en mi caso es un UIButton y todos los elementos secundarios también son UIButtons que pueden moverse fuera de los límites del UIButton principal.
Mejor
fuente
En la vista principal, puede anular el método de prueba de posicionamiento:
En este caso, si el punto cae dentro de los límites de su botón, reenvía la llamada allí; de lo contrario, vuelva a la implementación original.
fuente
En mi caso, tenía una
UICollectionViewCell
subclase que contenía unUIButton
. InhabilitéclipsToBounds
en la celda y el botón estaba visible fuera de los límites de la celda. Sin embargo, el botón no estaba recibiendo eventos táctiles. Pude detectar los eventos táctiles en el botón usando la respuesta de Jack: https://stackoverflow.com/a/30431157/3344977Aquí hay una versión Swift:
Rápido 4:
fuente
¿Por qué está pasando esto?
Esto se debe a que cuando su subvista se encuentra fuera de los límites de su supervista, los eventos táctiles que realmente suceden en esa subvista no se entregarán a esa subvista. Sin embargo, SERÁ ser entregado a su supervista.
¿Qué necesitas hacer?
Cuando su supervista reciba el evento táctil mencionado anteriormente, deberá decirle a UIKit explícitamente que mi subvista debería ser la que reciba este evento táctil.
¿Y el código?
En su supervista, implemente
func hitTest(_ point: CGPoint, with event: UIEvent?)
Gotchya fascinante: debes ir a la "supervista más alta demasiado pequeña"
Tienes que ir "arriba" a la vista "más alta" a la que se encuentra la vista del problema.
Ejemplo típico:
Digamos que tiene una pantalla S, con una vista de contenedor C. La vista del controlador de vista de contenedor es V. (Recuerde que V se ubicará dentro de C y tendrá el tamaño idéntico). V tiene una subvista (tal vez un botón) B. B es el problema vista que en realidad está fuera de V.
Pero tenga en cuenta que B también está fuera de C.
En este ejemplo, usted tiene que aplicar la solución
override hitTest
, de hecho, a C, no a V . Si lo aplica a V, no hace nada.fuente
Rápido:
Donde targetView es la vista en la que desea recibir el evento (que puede estar total o parcialmente ubicada fuera del marco de su vista principal).
fuente
Para mí (como para otros), la respuesta no fue anular el
hitTest
método, sino elpointInside
método. Tuve que hacer esto solo en dos lugares.La Supervista Esta es la opinión de que si se hubiera
clipsToBounds
establecido como verdadera, haría desaparecer todo este problema. Así que aquí está mi simpleUIView
en Swift 3:La subvista Su kilometraje puede variar, pero en mi caso también tuve que sobrescribir el
pointInside
método para la subvista que se había decidido que el toque estaba fuera de los límites. El mío está en Objective-C, entonces:Esta respuesta (y algunas otras sobre la misma pregunta) pueden ayudar a aclarar su comprensión.
fuente
swift 4.1 actualizado
Para obtener eventos táctiles en la misma UIView, solo necesita agregar el siguiente método de anulación, identificará la vista específica tocada en UIView que se coloca fuera del límite
fuente