ios - bottom - status bar iphone
¿Cómo ignorar los eventos táctiles y pasarlos a los objetos UIControl de otra subvista? (5)
Tengo un UIViewController personalizado cuya UIView ocupa una esquina de la pantalla, pero la mayor parte es transparente excepto por las partes que tienen algunos botones y otras cosas. Debido a la disposición de los objetos en esa vista, el marco de la vista puede cubrir algunos botones debajo de ella. Quiero poder ignorar los toques en esa vista si no tocan nada importante en ella, pero parece que solo puedo transmitir los eventos táctiles reales (cosas toquesEnded / siguienteResponder). Si tengo un UIButton o algo así que no usa toquesEnded, ¿cómo paso el evento táctil junto a eso?
No puedo determinar manualmente el selector de botones para llamar, porque este ViewController personalizado se puede usar en muchas vistas diferentes. Básicamente necesito una forma de llamar esto:
[self.nextResponder touchesEnded:touches withEvent:event];
en los tipos de UIControl también.
Esta es una vieja pregunta, y aparece en la parte superior de las búsquedas. Entonces, pensé que publicaría otra posible solución que podría funcionar mejor para su situación. En mi caso, quería arrastrar una etiqueta encima de otra etiqueta y quería poner la etiqueta a continuación en el hitTest. Lo más simple es configurar userInteractionEnabled
en NO
o false
, luego haga su userInteractionEnabled
de userInteractionEnabled
, y luego vuelva a establecerla si necesita moverla de nuevo. Aquí hay una muestra de código en Swift:
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
let location = touch?.locationInView(self.view)
self.label1.userInteractionEnabled = false
let view = self.view.hitTest(location!, withEvent: nil) as? UILabel
print(view?.text)
self.label1.userInteractionEnabled = true
}
Mi problema era similar: tenía un UIControl con respuestas táctiles complejas, pero actuaba de manera extraña cuando estaba incrustado en una vista de desplazamiento ...
Esto evita el desplazamiento de los padres (o puede modificarse para evitar otras interacciones) cuando la vista secundaria tiene un gesto táctil activo.
Mi solución:
Cree un protocolo de delegado para didBeginInteraction y didEndInteraction en la vista secundaria.
Llama a delegate.didBeginInteraction from touchesBegan
Llamar delegate.didEndInteraction de toquesEnded y toques cancelados
En el controlador principal, implemente los protocolos didBegin y didEnd, establezca el delegado
Luego configure scrollView.scrollEnabled = NO en didBegin, scrollEnabled = YES en didEnd.
Espero que esto ayude a alguien con un caso de uso ligeramente diferente a la pregunta planteada.
No he encontrado una buena manera de pasar eventos UITouch entre objetos. Lo que generalmente funciona mejor es implementar hitTest y devolver nil si el punto no está en la vista que desea manejarlo:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
Probablemente la mejor manera de hacerlo es anular hitTest:withEvent:
en la vista que quiere ignorar los toques. Dependiendo de la complejidad de su jerarquía de vistas, hay un par de maneras sencillas de hacerlo.
Si tiene una referencia a la vista debajo de la vista para ignorar:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
// If the hitView is THIS view, return the view that you want to receive the touch instead:
if (hitView == self) {
return otherView;
}
// Else return the hitView (as it could be one of this view''s buttons):
return hitView;
}
Si no tiene una referencia a la vista:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitView = [super hitTest:point withEvent:event];
// If the hitView is THIS view, return nil and allow hitTest:withEvent: to
// continue traversing the hierarchy to find the underlying view.
if (hitView == self) {
return nil;
}
// Else return the hitView (as it could be one of this view''s buttons):
return hitView;
}
Recomendaría el primer enfoque como el más sólido (si es posible obtener una referencia a la vista subyacente).
Swift respuesta:
Puede crear una subclase UIView, IgnoreTouchView. En un guión gráfico, configúralo en la (s) vista (s) de VC que deseas pasar a través de toques:
class IgnoreTouchView : UIView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if hitView == self {
return nil
}
return hitView
}
}
Tenga en cuenta que debe establecer UserInteractionEnabled en true, para la UIView en cuestión.