2014-03-27 18 views
9

Ich habe eine UIView, die als Unteransicht zu meinem View-Controller hinzugefügt wird. Ich habe einen bezier Pfad für diese Ansicht gezeichnet. Meine drawRect Implementierung ist unterErkennung von Tap in einem Bezier-Pfad

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    UIBezierPath *bpath = [UIBezierPath bezierPath]; 

    [bpath moveToPoint:CGPointMake(50, 50)]; 
    [bpath addLineToPoint:CGPointMake(100, 50)]; 
    [bpath addLineToPoint:CGPointMake(100, 100)]; 
    [bpath addLineToPoint:CGPointMake(50, 100)]; 
    [bpath closePath]; 

    CGContextAddPath(context, bpath.CGPath); 
    CGContextSetStrokeColorWithColor(context,[UIColor blackColor].CGColor); 
    CGContextSetLineWidth(context, 2.5); 
    CGContextStrokePath(context); 
    UIColor *fillColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.5 alpha:0.7]; 
    [fillColor setFill]; 
    [bpath fill]; 
} 

I Hahn in diesem Bezierpfad erkennen wollen, aber nicht der Punkt, der innerhalb des UIView und außerhalb des Weges ist. Zum Beispiel in diesem Fall, wenn meine Berührungskoordinate (10, 10) ist, sollte sie nicht erkannt werden. Ich weiß über CGContextPathContainsPoint, aber es hilft nicht, wenn Berührung innerhalb des Pfades ist. Gibt es eine Möglichkeit, Berührungsereignisse innerhalb des Bezier-Pfads zu erkennen?

+0

Vielleicht müssen Sie 'CGPathCloseSubpath' hinzufügen. Ich habe meine Antwort aktualisiert. Bitte prüfe. – Avt

+1

"detect tap innerhalb dieses Bezier-Pfades nicht innerhalb der UIView" Dieser Bezier-Pfad wird in der UIView gezeichnet, also wie kann ein Tap in ihm sein, aber nicht in der UIView? – matt

+0

@matt: bearbeitet die Frage – blancos

Antwort

13

Es gibt eine Funktion CGPathContainsPoint() es kann in Ihrem Fall nützlich sein.

Seien Sie auch vorsichtig, wenn Sie Gestenpunkt von Superview erhalten, die Koordinate stimmt möglicherweise nicht mit Ihrem Test überein. Sie haben ein Verfahren zur convertPoint von oder zu einem Koordinatensystem der bestimmte Ansicht:

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view 
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view 
+0

danke für den Vorsprung. –

8

Versuchen UIBezierPath der method:

func contains(_ point: CGPoint) -> Bool 

Gibt einen Booleschen Wert, der angibt, ob der Bereich durch den Empfänger eingeschlossen enthält die angegebener Punkt.

+1

CGPathCloseSubpath() akzeptiert bpath nicht als Argument. Ich habe versucht, bpath.CGPath auch – blancos

4

Erkennen Hahn in einem Bezier-Pfad in swift: -

Es ist einfach in neuesten schnellen folgenden Schritte aus, und Sie werden Ihre UIBezierPath Touch Veranstaltung.

Schritt 1: - Initialisieren Tippen Sie auf Ereignis in der Ansicht, wo Ihr UIBizerPath hinzugefügt wurde.

///Catch layer by tap detection let tapRecognizer:UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(YourClass.tapDetected(_:))) viewSlices.addGestureRecognizer(tapRecognizer)

Schritt 2: - Stellen "tapDetected" Methode

//MARK:- Hit TAP 
public func tapDetected(tapRecognizer:UITapGestureRecognizer){ 
    let tapLocation:CGPoint = tapRecognizer.locationInView(viewSlices) 
    self.hitTest(CGPointMake(tapLocation.x, tapLocation.y)) 


} 

Schritt 3: - Stellen "hitTest" letzte Methode

public func hitTest(tapLocation:CGPoint){ 
     let path:UIBezierPath = yourPath 
     if path.containsPoint(tapLocation){ 
      //tap detected do what ever you want ..;) 
     }else{ 
      //ooops you taped on other position in view 
     } 
    } 



Swift 4

: Schritt 1:Update - Initialisieren Tippen Ereignis auf Sicht, wo Ihre UIBeizerPath hinzugefügt.

///Catch layer by tap detection 
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourClass.tapDetected(tapRecognizer:))) 
viewSlices.addGestureRecognizer(tapRecognizer) 

Schritt 2: - Stellen "tapDetected" method

public func tapDetected(tapRecognizer:UITapGestureRecognizer){ 
    let tapLocation:CGPoint = tapRecognizer.location(in: viewSlices) 
    self.hitTest(tapLocation: CGPoint(x: tapLocation.x, y: tapLocation.y)) 
} 

Schritt 3: - Stellen "hitTest" letzte Methode

private func hitTest(tapLocation:CGPoint){ 
    let path:UIBezierPath = yourPath 

    if path.contains(tapLocation){ 
     //tap detected do what ever you want ..;) 
    }else{ 
     //ooops you taped on other position in view 
    } 
} 
+0

@ Diogo Souza danke für neues Update! :) –

+0

Kein Problem! Danke für die gute Antwort! ^^ –

1

Eine Lösung in Swift 3 .1 (Portierung über die von Apple empfohlene Lösung von here)

func containsPoint(_ point: CGPoint, path: UIBezierPath, inFillArea: Bool) -> Bool { 

     UIGraphicsBeginImageContext(self.size) 

     let context: CGContext? = UIGraphicsGetCurrentContext() 
     let pathToTest = path.cgPath 
     var isHit = false 

     var mode: CGPathDrawingMode = CGPathDrawingMode.stroke 

     if inFillArea { 

      // check if UIBezierPath uses EO fill 
      if path.usesEvenOddFillRule { 
       mode = CGPathDrawingMode.eoFill 
      } else { 
       mode = CGPathDrawingMode.fill 
      } 
     } // else mode == stroke 

     context?.saveGState() 
     context?.addPath(pathToTest) 

     isHit = (context?.pathContains(point, mode: mode))! 
     context?.restoreGState() 

     return isHit 
     }