2013-04-30 2 views
8

Nun, ich denke, es am besten ist, zu zeigen, was ich meine:Was ist los mit der Größe von UIButtons Touch Drag/Exit-Trefferbereich?

Animation of a UIButton reacting to dragging motions

Man kann deutlich sehen, dass, wenn wir auf den Knopf und zogen es aus berührt haben, ein konsequentes Einzug in Ereignis löst die Knopfzustandswechsel von weit weg.

Während dieses Verhalten für alle UIButtons natürlich ist, konnte ich keine Lösung googlen, um es zu ändern.

Gibt es eine Möglichkeit, den Trefferbereich für diese Art von UIButton-Empfindlichkeit zu reduzieren? Ich möchte, dass es reduziert wird, weil ich denke, dass der Knopf groß genug ist, wie es ist, und es wird eine bessere Benutzererfahrung zusammen mit Up/Down-Soundeffekten bieten.

UPD: Die folgende Aufhebungscode für UIButton wurde in another thread geschrieben:

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

Es ändert die Erweiterung Trefferfläche durch Ziehen verwendet In/Out Ereignisse Ziehen, doch Taste Up/Down Zustände wechseln genau genauso wie zuvor.

+1

scheint wie ein Duplikat dieser Frage: http://stackoverflow.com/questions/14340122/uicontroleventtouchdragexit-triggers-when-100-pixels-away- from-uibutton –

+1

Ja, fast, aber die dort zur Verfügung gestellte Antwort ändert nicht die Taste Up/Down. Sie scheinen auf etwas anderes mit 100.0f Trefferbereichserweiterung angewiesen zu sein. – Kai

Antwort

1

Ich weiß nicht, ob Sie immer noch das gleiche Problem haben, aber ich konnte es beheben, indem Sie ähnlichen Code in der touchseEnded: withEvent: -Methode verwenden.

Ich habe diese Methode auch geändert, um touchEnter und dragInside hinzuzufügen, da diese mit Ereignissen im aktuellen Code immer noch die gleichen Grenzen hatten. Zusätzlich habe ich jeden der Fälle mit YES versehen, so dass der Super nicht aufgerufen wird (es würde dazu führen, dass der Berührungswiderstand vorzeitig aufgerufen wird).

Hier ist der letzte Code, den ich mit endete, in zwei Methoden:

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

HINWEIS: die Super des Verfahrens am Ende Rückkehr ist nicht notwendig, aber ich habe es auf Vollständigkeit drin.

2

A Swift Version:

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) 
    } 
    }