2013-04-30 4 views
8

Beh, credo che sia meglio per mostrare quello che voglio dire:Che succede con le dimensioni di UIButton's Touch Trascina/Esci da hit area?

Animation of a UIButton reacting to dragging motions

Si può vedere chiaramente che una volta che abbiamo toccato il tasto e si è trasferito fuori di esso, con conseguente evento move-in innesca la lo stato del pulsante cambia da molto lontano.

Mentre questo comportamento è naturale per tutti gli UIButtons, non ho potuto google una soluzione per alterarlo.

C'è un modo per ridurre l'area attiva per questo tipo di sensibilità UIB? Lo voglio ridimensionato, perché sento che il pulsante è abbastanza grande così com'è, e fornirà un'esperienza utente migliore con effetti sonori su/giù.

UPD: Il seguente codice di override per UIButton è stato pubblicato in another thread:

- (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]; 
} 

altera l'estensione area attiva usata da trascinare nella/trascinare eventi, eppure Button Up stati/Giù passare esattamente la come prima.

+1

sembra un duplicato di questa domanda: http://stackoverflow.com/questions/14340122/uicontroleventtouchdragexit-triggers-when-100-pixels-away- from-uibutton –

+1

Sì, quasi, ma la risposta fornita non cambia gli stati Up/Down del pulsante. Sembrano dipendere da qualcos'altro con estensione dell'area colpita 100.0f. – Kai

risposta

1

Non so se si sta ancora avendo lo stesso problema, ma sono stato in grado di risolverlo usando un codice simile nel touchesEnded: withEvent: method.

Ho anche modificato questo metodo per aggiungere touchEnter e dragInside perché con il codice corrente, quelli per gli eventi hanno ancora utilizzato gli stessi limiti. Inoltre, ho fatto in modo che ognuno dei casi restituisse SÌ in modo che il super non venga chiamato (causerebbe il trascinamento del tocco all'interno per essere chiamato prematuramente).

Ecco il codice finale che ho finito con, in due metodi:

- (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) { 
      [self sendActionsForControlEvents:UIControlEventTouchDragExit]; 
      return YES; 
     } 
     else 
     { 
      [self sendActionsForControlEvents:UIControlEventTouchDragOutside]; 
      return YES; 
     } 
    } 
    else { 
     BOOL previousTouchOutside = !CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]); 
     if (previousTouchOutside) { 
      [self sendActionsForControlEvents:UIControlEventTouchDragEnter]; 
      return YES; 
     } 
     else { 
      [self sendActionsForControlEvents:UIControlEventTouchDragInside]; 
      return YES; 
     } 
    } 
    return [super continueTrackingWithTouch:touch withEvent:event]; 
} 


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGFloat boundsExtension = 25.0f; 
    CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension); 

    BOOL touchInside = CGRectContainsPoint(outerBounds, [touch locationInView:self]); 
    if (touchInside) { 
     return [self sendActionsForControlEvents:UIControlEventTouchUpInside]; 
    } 
    else { 
     return [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; 
    } 
    return [super endTrackingWithTouch:touch withEvent:event]; 
} 

NOTA: Tornando il super del metodo, alla fine non è necessario, ma l'ho lasciato lì per completezza. Versione

2

A Swift:

private let _boundsExtension: CGFloat = 0 // Adjust this as needed 

    override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent?) -> Bool { 
    let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension) 
    let currentLocation: CGPoint = touch.locationInView(self) 
    let previousLocation: CGPoint = touch.previousLocationInView(self) 

    let touchOutside: Bool = !CGRectContainsPoint(outerBounds, currentLocation) 
    if touchOutside { 
     let previousTouchInside: Bool = CGRectContainsPoint(outerBounds, previousLocation) 
     if previousTouchInside { 
     sendActionsForControlEvents(.TouchDragExit) 
     } else { 
     sendActionsForControlEvents(.TouchDragOutside) 
     } 
    } else { 
     let previousTouchOutside: Bool = !CGRectContainsPoint(outerBounds, previousLocation) 
     if previousTouchOutside { 
     sendActionsForControlEvents(.TouchDragEnter) 
     } else { 
     sendActionsForControlEvents(.TouchDragInside) 
     } 
    } 

    return true 
    } 

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    let touch: UITouch = touches.first! 
    let outerBounds: CGRect = CGRectInset(bounds, -1 * _boundsExtension, -1 * _boundsExtension) 
    let currentLocation: CGPoint = touch.locationInView(self) 

    let touchInside: Bool = CGRectContainsPoint(outerBounds, currentLocation) 
    if touchInside { 
     return sendActionsForControlEvents(.TouchUpInside) 
    } else { 
     return sendActionsForControlEvents(.TouchUpOutside) 
    } 
    } 
Problemi correlati