2017-05-30 1 views
0

Ich habe Probleme beim Erkennen von Konturen, die transformiert wurden.Erkennen von Berührung auf transformierten Shapeslayer

Touch ignoriert die Transformation und erkennt die Schicht an der falschen Position.

Schritte zum Reproduzieren:

I eine benutzerdefinierte Ansicht erstellen, wo ich die Zieh außer Kraft: Verfahren zur Herstellung eine Anzahl von Pfaden, auf Formen Schichten zu erzeugen.

Die Formebenen sind transformiert zu einer neuen Position und Größe in der Ansicht.

Wenn ich versuche festzustellen, ob eine Formschicht berührt wurde, befindet sich die Erkennung an der falschen Stelle.

Mit Blick auf den Screenshot unten ist die rote Shape-Ebene, was in der Ansicht gezeichnet wird.

Die umrissene Form ist die ursprüngliche nicht transformierte Form (dies ist nicht in der Ansicht gezeichnet).

enter image description here

Wenn ich die rote Form Schicht berühren, wird nichts erkannt.

Wenn Sie den Bildschirm berühren, auf dem die ursprüngliche Form ohne Transformationen wäre, wird die Formebene erkannt!

Dies bedeutet, dass die Formebene auf einem leeren Teil des Bildschirms erkannt wird.

-Code zu reproduzieren:

@IBDesignable 
class CustomView: UIView { 

    let bezierPaths: [UIBezierPath] = MyShapes.headShape() 

    override func draw(_ rect: CGRect) { 

     //draw each bezierPath onto its own shape layer 
     for bezierPath in bezierPaths { 

      let shapeLayer = CAShapeLayer() 

      shapeLayer.fillColor = UIColor.red.cgColor 
      shapeLayer.strokeColor = UIColor.red.cgColor 
      shapeLayer.lineWidth = 1 
      shapeLayer.path = bezierPath.cgPath 

      //transform shape to new size and position in view 
      let scale = CGAffineTransform(scaleX: 1.5, y: 1.5) 
      let transform = CGAffineTransform(translationX: 100, y: 100) 
      let affineTransform = scale.concatenating(transform) 
      shapeLayer.setAffineTransform(affineTransform) 

      //add the shape layer to the view 
      self.layer.addSublayer(shapeLayer) 

     } 

    } 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

     for touch in touches { 
      let touchLocation = touch.location(in: self) 

      for sublayer in self.layer.sublayers! { 

       if let shapeLayer = sublayer as? CAShapeLayer { 
        if shapeLayer.path!.contains(touchLocation) { 

         print("touched the shape layer") 

        } 
       } 

      } 

     }   

    } 

} 


class MyShapes { 

    static func headShape() -> [UIBezierPath] { 

     var paths = [UIBezierPath]() 

     let frame: CGRect = CGRect(x: 0, y: 0, width: 285, height: 508) 

     //create shape and add to array 
     let head_FrontPath = UIBezierPath() 
     head_FrontPath.move(to: CGPoint(x: frame.minX + 164.47, y: frame.minY + 34.31)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 165.1, y: frame.minY + 28.52), controlPoint1: CGPoint(x: frame.minX + 164.76, y: frame.minY + 32.42), controlPoint2: CGPoint(x: frame.minX + 165, y: frame.minY + 30.44)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 161.97, y: frame.minY + 12.86), controlPoint1: CGPoint(x: frame.minX + 165.42, y: frame.minY + 22.25), controlPoint2: CGPoint(x: frame.minX + 163.22, y: frame.minY + 15.36)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 149.75, y: frame.minY + 0.95), controlPoint1: CGPoint(x: frame.minX + 160.72, y: frame.minY + 10.35), controlPoint2: CGPoint(x: frame.minX + 155.7, y: frame.minY + 3.15)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.5, y: frame.minY + 0.1), controlPoint1: CGPoint(x: frame.minX + 146.73, y: frame.minY - 0.16), controlPoint2: CGPoint(x: frame.minX + 144.37, y: frame.minY + 0.1)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 135.25, y: frame.minY + 0.95), controlPoint1: CGPoint(x: frame.minX + 140.63, y: frame.minY + 0.1), controlPoint2: CGPoint(x: frame.minX + 138.28, y: frame.minY - 0.16)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 123.03, y: frame.minY + 12.86), controlPoint1: CGPoint(x: frame.minX + 129.3, y: frame.minY + 3.15), controlPoint2: CGPoint(x: frame.minX + 124.29, y: frame.minY + 10.35)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 119.9, y: frame.minY + 28.52), controlPoint1: CGPoint(x: frame.minX + 121.78, y: frame.minY + 15.36), controlPoint2: CGPoint(x: frame.minX + 119.59, y: frame.minY + 22.25)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 120.6, y: frame.minY + 34.76), controlPoint1: CGPoint(x: frame.minX + 120, y: frame.minY + 30.59), controlPoint2: CGPoint(x: frame.minX + 120.28, y: frame.minY + 32.73)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 117.33, y: frame.minY + 37.38), controlPoint1: CGPoint(x: frame.minX + 119.21, y: frame.minY + 35.05), controlPoint2: CGPoint(x: frame.minX + 116.96, y: frame.minY + 36.32)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 122.02, y: frame.minY + 48.93), controlPoint1: CGPoint(x: frame.minX + 117.83, y: frame.minY + 38.83), controlPoint2: CGPoint(x: frame.minX + 120.95, y: frame.minY + 50.57)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 122.31, y: frame.minY + 47.94), controlPoint1: CGPoint(x: frame.minX + 122.15, y: frame.minY + 48.73), controlPoint2: CGPoint(x: frame.minX + 122.25, y: frame.minY + 48.39)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 124.28, y: frame.minY + 58.91), controlPoint1: CGPoint(x: frame.minX + 122.66, y: frame.minY + 51.97), controlPoint2: CGPoint(x: frame.minX + 123.39, y: frame.minY + 57.57)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 134.31, y: frame.minY + 64.55), controlPoint1: CGPoint(x: frame.minX + 125.54, y: frame.minY + 60.79), controlPoint2: CGPoint(x: frame.minX + 132.74, y: frame.minY + 64.24)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.23, y: frame.minY + 66.38), controlPoint1: CGPoint(x: frame.minX + 135.73, y: frame.minY + 64.83), controlPoint2: CGPoint(x: frame.minX + 140.24, y: frame.minY + 66.14)) 
     head_FrontPath.addLine(to: CGPoint(x: frame.minX + 142.23, y: frame.minY + 66.43)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.5, y: frame.minY + 66.4), controlPoint1: CGPoint(x: frame.minX + 142.3, y: frame.minY + 66.43), controlPoint2: CGPoint(x: frame.minX + 142.41, y: frame.minY + 66.41)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 142.77, y: frame.minY + 66.43), controlPoint1: CGPoint(x: frame.minX + 142.58, y: frame.minY + 66.41), controlPoint2: CGPoint(x: frame.minX + 142.7, y: frame.minY + 66.43)) 
     head_FrontPath.addLine(to: CGPoint(x: frame.minX + 142.77, y: frame.minY + 66.38)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 150.69, y: frame.minY + 64.55), controlPoint1: CGPoint(x: frame.minX + 144.75, y: frame.minY + 66.14), controlPoint2: CGPoint(x: frame.minX + 149.27, y: frame.minY + 64.83)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 160.71, y: frame.minY + 58.91), controlPoint1: CGPoint(x: frame.minX + 152.26, y: frame.minY + 64.23), controlPoint2: CGPoint(x: frame.minX + 159.46, y: frame.minY + 60.79)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 162.71, y: frame.minY + 47.63), controlPoint1: CGPoint(x: frame.minX + 161.63, y: frame.minY + 57.54), controlPoint2: CGPoint(x: frame.minX + 162.37, y: frame.minY + 51.68)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 162.97, y: frame.minY + 48.46), controlPoint1: CGPoint(x: frame.minX + 162.77, y: frame.minY + 48), controlPoint2: CGPoint(x: frame.minX + 162.86, y: frame.minY + 48.29)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 167.67, y: frame.minY + 36.91), controlPoint1: CGPoint(x: frame.minX + 164.05, y: frame.minY + 50.1), controlPoint2: CGPoint(x: frame.minX + 167.16, y: frame.minY + 38.36)) 
     head_FrontPath.addCurve(to: CGPoint(x: frame.minX + 164.47, y: frame.minY + 34.31), controlPoint1: CGPoint(x: frame.minX + 168.03, y: frame.minY + 35.87), controlPoint2: CGPoint(x: frame.minX + 165.87, y: frame.minY + 34.63)) 
     head_FrontPath.close() 
     paths.append(head_FrontPath) 

     //create a number of other shapes 
     //... 
     //... 
     //... 

     //return array of shapes 
     return paths 
    } 

} 

Wie kann ich die umgewandelt erkennen Form in der richtigen Position auf dem Bildschirm Touch verwenden?

+1

IIRC von meinem Mathematikunterricht, müssen Sie die umgekehrte affine gelten für Ihre 'touchLocation' Ihrer Schicht verwandeln bevor Sie es testen. – Cyrille

+0

Ja, Sie haben Recht. Es funktionierte einmal umgekehrt. Vielen Dank. –

+0

Bitte können Sie als Antwort posten. Dies hat den Trick gemacht: Lassen Sie touchLocation = touch.location (in: self) .applying (affineTransform.inverted()) –

Antwort

0

Sie haben die umgekehrte affine anzuwenden Ihrer Schicht auf Ihre touchLocation verwandeln, bevor es zu testen:

let touchLocation = touch.location(in: self).applying(affineTransform.inverted()) 
Verwandte Themen