UIControlEventTouchDragExit se dispara cuando se encuentran a 100 píxeles de distancia del button UIB

En la actualidad, el UIControlEventTouchDragExit solo se activa al arrastrar 100 píxeles desde el button. Me gustaría personalizar este comportamiento y poner ese range en alnetworkingedor de 25 píxeles, pero soy relativamente nuevo en la progtwigción y nunca he necesitado anular / personalizar un método integrado como este.

He leído en algunas otras publicaciones aquí que necesitaría subclasificar el UIButton (o tal vez incluso UIControl ?), Y anular -(BOOL) beginTrackingWithTouch: (UITouch *) touch withEvent: (UIEvent *) event y methods relacionados, pero realmente no sé dónde comenzar a hacerlo.

¿Podría alguien amablemente ofrecer algún consejo sobre cómo podría lograr esto? ¡Muy apreciado! ^ _ ^

Anular continueTrackingWithTouch: withEvent: así para enviar events DragExit / DragOutside dentro del canal pnetworkingeterminado:

 - (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { CGFloat boundsExtension = 25.0f; CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension); BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:self]); if(touchOutside) { BOOL previousTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]); if(previousTouchInside) { NSLog(@"Sending UIControlEventTouchDragExit"); [self sendActionsForControlEvents:UIControlEventTouchDragExit]; } else { NSLog(@"Sending UIControlEventTouchDragOutside"); [self sendActionsForControlEvents:UIControlEventTouchDragOutside]; } } return [super continueTrackingWithTouch:touch withEvent:event]; } 

Encontré que la respuesta aceptada tiene dos problemas.

  1. Las acciones registradas se llamarían dos veces:
    • la primera vez es cuando el dedo abandona el control 25 píxeles, que se establece en el método sobrescrito.
    • la segunda vez se llama cuando el dedo abandona el control unos 70 píxeles, que es el comportamiento pnetworkingeterminado del UIControl.
  2. El segundo problema es la position recuperada del parámetro de event es (0, 0) , no se inicializa correctamente.

Encontré otra forma de lograr este propósito basado en esta respuesta, la idea básica es manejar el evento en las devoluciones de llamada en lugar de sobrescribir ese método. Hay dos pasos:

Registre las acciones:

  // to get the touch up event [btn addTarget:self action:@selector(btnTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpInside]; [btn addTarget:self action:@selector(btnTouchUp:withEvent:) forControlEvents:UIControlEventTouchUpOutside]; // to get the drag event [btn addTarget:self action:@selector(btnDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside]; [btn addTarget:self action:@selector(btnDragged:withEvent:) forControlEvents:UIControlEventTouchDragOutside]; 

Manejar los events:

 - (void)btnTouchUp:(UIButton *)sender withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; CGFloat boundsExtension = 25.0f; CGRect outerBounds = CGRectInset(sender.bounds, -1 * boundsExtension, -1 * boundsExtension); BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]); if (touchOutside) { // UIControlEventTouchUpOutside } else { // UIControlEventTouchUpInside } } - (void)btnDragged:(UIButton *)sender withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; CGFloat boundsExtension = 25.0f; CGRect outerBounds = CGRectInset(sender.bounds, -1 * boundsExtension, -1 * boundsExtension); BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:sender]); if (touchOutside) { BOOL previewTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]); if (previewTouchInside) { // UIControlEventTouchDragExit } else { // UIControlEventTouchDragOutside } } else { BOOL previewTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:sender]); if (previewTouchOutside) { // UIControlEventTouchDragEnter } else { // UIControlEventTouchDragInside } } } 

Ahora todos los seis events se pueden manejar con la extensión de límites de 25 píxeles, por supuesto, puedes establecer este valor en otros como desees.

De acuerdo a lo que leo aquí

Apple pone 100 píxeles para explicar la inexactitud de usar un dedo. Puede sobrescribir los methods usando:

  • -(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
  • -(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

Y otros methods relacionados. Documentación de Apple