0

Suppose you have a CALayer subclass as part of your view hierarchy, which has been created with a scale and rotation transform, where the angle and scale is only defined at runtime, i.e:

let layer = CALayer()
layer.frame = CGRect(x: 10, y: 10, width: 100, height: 100)

//where xx and yy are some precomputed values
layer.transform = CATransform3DConcat(CATransform3DMakeScale(xx, xx, 1), 
                                      CATransform3DMakeRotation(yy, 0, 0, 1)) 

let view = UIView() //your view hierarchy
view.addSublayer(layer)

Later in the program, I want to rotate this layer to a specific angle. How do I specify the transform so that

  • A) The original scale applied to the layer is preserved
  • B) The original rotation applied to the layer is discarded and reset to the new value?
let angle = CGFloat.pi/3
layer.transform = ???
Danny Bravo
  • 4,534
  • 1
  • 25
  • 43

1 Answers1

2

You can reapply your transform again having xx value unchanged

    func rotateLayer(by angle: CGFloat) {
        layer.transform = CATransform3DConcat(CATransform3DMakeScale(xx, xx, 1),
        CATransform3DMakeRotation(angle, 0, 0, 1))
    }

Edit

Based on this answer you can get and reuse uniform scale factor like this

    func rotateLayer(by angle: CGFloat) {
        let scale = sqrt(pow(layer.transform.m11, 2) + pow(layer.transform.m12, 2))
        print(scale)
        layer.transform = CATransform3DConcat(CATransform3DMakeScale(scale, scale, 1), CATransform3DMakeRotation(angle, 0, 0, 1))
    }
schmidt9
  • 4,436
  • 1
  • 26
  • 32
  • How do I get the value of xx after it’s been applied? Is the only option to keep the value in memory? – Danny Bravo Dec 23 '19 at 16:45
  • @DannyBravo sorry I don't know how to get scale values back from transform, maybe we should make some calculations based on matrix values of transform (`m11` and `m22` which keep scale values, but in transformed form taking rotation into account) – schmidt9 Dec 23 '19 at 17:11