2

I am using the following code to scale a CAShapelayer instance (i.e., self.view.layer.sublayers![0]):

class ViewController: UIViewController {   
override func viewDidLoad()
{
    super.viewDidLoad()
    self.view = Map(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height))
    let pinchGR = UIPinchGestureRecognizer(target: self, action: #selector(self.didPinch(_:)))
    self.view.addGestureRecognizer(pinchGR)
}

@objc func didPinch(_ pinchGR: UIPinchGestureRecognizer)
{
    let transformation = CGAffineTransform(a: pinchGR.scale, b: 0, c: 0, d: pinchGR.scale, tx: 0, ty: 0)
    if pinchGR.state == .began || pinchGR.state == .changed
    {
        self.view.layer.sublayers![0].setAffineTransform(transformation)
    }
}}

class Map: UIView{
override init(frame: CGRect)
{
    super.init(frame: frame)
    self.backgroundColor = UIColor.blue
    drawTestShape()
}
required init?(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder)
}
func drawTestShape()
{
    let shapeLayer = CAShapeLayer()
    shapeLayer.frame = self.frame
    let path = UIBezierPath()
    shapeLayer.lineWidth = 5.0
    shapeLayer.fillColor = nil
    shapeLayer.strokeColor = UIColor.white.cgColor
    shapeLayer.backgroundColor = UIColor.red.cgColor
    path.move(to: CGPoint(x:200,y:200))
    path.addLine(to: CGPoint(x:300,y:300))
    path.addLine(to: CGPoint(x:100,y:300))
    path.close()
    shapeLayer.path = path.cgPath
    self.layer.addSublayer(shapeLayer)
}}

The scaling is performed correctly in the first pinch gesture. However, when a second pinch gesture is applied, the CAShapelayer instance starts again from its initial size, and not from the size it had after the first gesture.

ckc
  • 345
  • 4
  • 12
  • Matt you are right this is not necessary, I removed it, but the problem I have posted is still there. – ckc Feb 18 '18 at 16:46
  • 1
    Okay, but I can only go on the information you show. You need to provide enough relevant code to allow the problem to be reproduced, and explain how to reproduce it. Scaling a bare layer like this is a very odd thing to do. Why don't you scale a view? Why don't you use a scroll view which already knows how to respond to a pinch by zooming? – matt Feb 18 '18 at 16:51
  • I have added the complete code. My target is the creation of a map. – ckc Feb 18 '18 at 17:05
  • I have reached to the decision to scale the layer from "Core Animation Programming Guide". I also used this way since: - I will add a sublayer that will show the user's position using a circle, and this sublayer must not be scaled, - I have the impression that the layer scaling is faster, and - I want all the screen to have the pinch gesture capability, even if the layer has been zoomed to a smaller size. (I am new in IOS programming, so the aforementioned may be not correct) – ckc Feb 18 '18 at 17:19
  • Well, I'm not persuaded, but I've provided code that translates the standard tried-and-true pattern for a pinch gesture on a view, adapted to a layer instead. – matt Feb 18 '18 at 17:58

1 Answers1

1

I can't really get behind the idea of scaling a layer, but if you must do it, try something more like this; this is the standard pattern for implementing a pinch gesture recognizer, so it's really best to stick with it:

@IBAction func didPinch(_ pinchGR: UIPinchGestureRecognizer) {
    self.view.layer.sublayers![0].setAffineTransform(
        self.view.layer.sublayers![0].affineTransform().scaledBy(
            x:pinchGR.scale, y:pinchGR.scale))
    pinchGR.scale = 1.0;
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • It works perfectly. Matt thank you very much for your help! I will also try the case of scaling a view, as you advised me (probably by adding a subview, adding the shapelayer on it and performing the animation on this subview instead of the layer). I appreciate your interest, have a nice day :) – ckc Feb 18 '18 at 18:07
  • You do not add the shape layer as a sublayer of the view; you make the view _host_ the shape layer _as its primary layer_. – matt Feb 18 '18 at 18:15
  • Thank you for the advice. I will try it and probably come back with new questions! – ckc Feb 18 '18 at 18:18