¿Es posible que un UIButton (o cualquier otro control para el caso) reciba eventos táctiles cuando el marco de UIButton se encuentra fuera del marco de su padre? Porque cuando intento esto, mi UIButton parece no poder recibir ningún evento. ¿Cómo trabajo alrededor de esto?interacción más allá de los límites de uiview
Respuesta
Sí. Puede anular el método hitTest:withEvent:
para devolver una vista para un conjunto de puntos más grande que el que contiene la vista. Vea el UIView Class Reference.
Editar: Ejemplo:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGFloat radius = 100.0;
CGRect frame = CGRectMake(-radius, -radius,
self.frame.size.width + radius,
self.frame.size.height + radius);
if (CGRectContainsPoint(frame, point)) {
return self;
}
return nil;
}
Edición 2: (Después de la clarificación :) Con el fin de asegurar que el botón se trata como si fuera dentro de los límites de los padres, se debe redefinir pointInside:withEvent:
en el padre para incluir el marco del botón.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint(self.view.bounds, point) ||
CGRectContainsPoint(button.view.frame, point))
{
return YES;
}
return NO;
}
Nota el código sólo existe para anular pointInside no es del todo correcta. Como Invocar explica a continuación, hacer esto:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint(self.oversizeButton.frame, point))
return YES;
return [super pointInside:point withEvent:event];
}
Tenga en cuenta que habías muy probable que lo hace con self.oversizeButton
como IBOutlet en esta subclase UIView; entonces puedes simplemente arrastrar el "botón de gran tamaño" en cuestión, hacia la vista especial en cuestión. (O, si por alguna razón ha estado haciendo esto mucho en un proyecto, tendría una subclase UIButton especial, y podría mirar a través de su lista de subvista para esas clases.) Espero que ayude.
¿Puede ayudarme a implementar esto correctamente con algún código de muestra? También leo la referencia y debido a la siguiente línea, estoy confundido: "Los puntos que se encuentran fuera de los límites del receptor nunca se informan como aciertos, incluso si se encuentran dentro de una de las subvistas del receptor. Las subvistas pueden extenderse visualmente más allá de los límites. de su padre si la propiedad clipsToBounds de la vista principal está establecida en NO. Sin embargo, la prueba de impacto siempre ignora los puntos fuera de los límites de la vista principal." – ThomasM
Especialmente esta parte hace que parezca que esta no es la solución que necesito:" Sin embargo, la prueba de impacto siempre ignora puntos fuera de los límites de la vista principal "... Pero podría estar equivocado, por supuesto, a veces encuentro las referencias de la manzana realmente confuso ... – ThomasM
Ah, ya lo entiendo. Necesitas anular el 'pointInside: withEvent:' de los padres para incluir el marco del botón. Añadiré un código de muestra a mi respuesta anterior. – jnic
@jnic, estoy trabajando en iOS SDK 5.0 y con el fin de obtener su código de trabajo que tenía derecho a hacer esto:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if (CGRectContainsPoint(button.frame, point)) {
return YES;
}
return [super pointInside:point withEvent:event]; }
La vista recipiente 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 padre.
Mejor
Swift:
Dónde TargetView es la vista que desea recibir el evento (que puede ser total o parcialmente situado fuera del marco de la vista padre).
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
let pointForTargetView: CGPoint = targetView.convertPoint(point, fromView: self)
if CGRectContainsPoint(targetView.bounds, pointForTargetView) {
return closeButton
}
return super.hitTest(point, withEvent: event)
}
En el padre vista se puede anular el método de prueba de posicionamiento:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint translatedPoint = [_myButton convertPoint:point fromView:self];
if (CGRectContainsPoint(_myButton.bounds, translatedPoint)) {
return [_myButton hitTest:translatedPoint withEvent:event];
}
return [super hitTest:point withEvent:event];
}
En este caso, si el punto cae dentro de los límites de su botón, reenvía la llamada allí; si no, vuelva a la implementación original.
En mi caso, tuve una subclase UICollectionViewCell
que contenía UIButton
. 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.Yo era capaz de detectar los eventos de toque en el botón mediante la respuesta de Jack: https://stackoverflow.com/a/30431157/3344977
Aquí hay una versión Swift:
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
let translatedPoint = button.convertPoint(point, fromView: self)
if (CGRectContainsPoint(button.bounds, translatedPoint)) {
print("Your button was pressed")
return button.hitTest(translatedPoint, withEvent: event)
}
return super.hitTest(point, withEvent: event)
}
Para mí (como para otros), la respuesta fue no para anular el hitTest
método, sino más bien el método pointInside
. Tenía que hacer esto solo en dos lugares.
El Superview Esta es la opinión de que si tuviera clipsToBounds
establece en true, que haría todo este problema desaparece. Así que aquí es mi sencilla UIView
en Swift 3:
class PromiscuousView : UIView {
override func point(inside point: CGPoint,
with event: UIEvent?) -> Bool {
return true
}
}
la subvista Su kilometraje puede variar, pero en mi caso también tuve que sobreescribir el método pointInside
para la subvista que se había decidido el toque estaba fuera de límites. El mío es en Objective-C, por lo que:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
WEPopoverController *controller = (id) self.delegate;
if (self.takeHitsOutside) {
return YES;
} else {
return [super pointInside:point withEvent:event];
}
}
This answer (y algunos otros en la misma pregunta) puede ayudar a aclarar su comprensión.
¿Por qué sucede esto?
Esto se debe a que cuando su subvista se encuentra fuera de los límites de su supervista, los eventos que realmente suceden en esa subvista no se entregarán a esa subvista. Sin embargo, se entregará WILL a su super visión.
Independientemente de si las subvistas se recortan visualmente o no, los eventos táctiles siempre respetan los límites del rectángulo de la supervista de la vista de destino. En otras palabras, los eventos táctiles que ocurren en una parte de una vista que se encuentra fuera del rectángulo de límites de su supervista no se entregan a esa vista. Link
Lo que hay que hacer?
Cuando su supervista recibe el evento táctil mencionado anteriormente, tendrá que decirle a UIKit explícitamente que mi subvista debe ser la que reciba este evento táctil.
¿Qué pasa con el código?
En su supervista, implementar func hitTest(_ point: CGPoint, with event: UIEvent?)
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if isHidden || alpha == 0 || clipsToBounds { return nil }
// convert the point into subview's coordinate system
let subviewPoint = self.convert(point, to: subview)
// if the converted point lies in subview's bound, tell UIKit that subview should be the one that receives this event
if ! subview.isHidden && subview.bounds.contains(subviewPoint) { return subview }
return nil
}
¡Gracias por esto! He pasado horas y horas sobre un problema derivado de esto. Realmente aprecio que se tome el tiempo para publicar esto. :) – ClayJ
- 1. imagen va más allá de los límites de contenedores div
- 2. [NSMutableArray objectAtIndex:]: índice 0 más allá de los límites para la matriz vacía de AVURLAsset
- 3. Más allá de los patrones de diseño?
- 4. [NSMutableArray objectAtIndex:]: índice 0 más allá de los límites para la matriz vacía '
- 5. dibujar fuera de los límites de UIView desde drawRect
- 6. UIView dibujar la sombra más allá del marco de la vista
- 7. índice 0 allá de los límites de error de matriz vacía
- 8. UIView ocultar vistas de niños cuando está fuera de límites
- 9. Python, más allá de lo básico
- 10. cambiar los límites de la propiedad de UIView no afecta su contenido
- 11. ¿Cómo dejo que mi trama matplotlib vaya más allá de los ejes?
- 12. Mover fábricas más allá en Python
- 13. Límites de los solucionadores SMT
- 14. trenzado y WebSockets: Más allá del eco
- 15. Obtener los límites de un MKMapView
- 16. UIView. ¿Cuáles son las dimensiones máximas de los límites que puedo usar?
- 17. Ir más allá de la función de optimización de R
- 18. Servicio de interacción vs Objetos de solicitud de interacción
- 19. Aplicaciones de litio que van más allá de CRUD
- 20. Imagen de fondo cortó más allá de la ventana gráfica
- 21. Seguridad más allá de un nombre de usuario/contraseña?
- 22. Falló la recuperación de la tarea más allá de max_retries
- 23. Emacs se desplacen más allá del extremo de tampón
- 24. Aplicar comprobación específica (más allá de los tipos de Moose) al atributo de Moose
- 25. ¿Son los vectores más rigurosos al marcar fuera de los límites que las matrices de montón?
- 26. PHPExcel - lee más allá de la última fila
- 27. Error: allowDefinition = 'MachineToApplication' más allá del nivel de aplicación
- 28. iOS cómo depurar bloqueos sin un seguimiento de la pila como: [__NSArrayM objectAtIndex:]: índice 0 más allá de los límites para la matriz vacía?
- 29. Dibujo fuera de los límites de UITableViewCell
- 30. ¿Cómo crece más allá de los marcos web para crear su propio marco de aplicación?
Esto también es bueno y relevante (o tal vez una víctima): http://stackoverflow.com/a/31420820/8047 –
Esto funciona perfectamente para mí. https://developer.apple.com/library/ios/qa/qa2013/qa1812.html Best –