Refresh CALayer rotation

I am trying to update the current rotation (and sometimes position) of the CALayer.

I am trying to follow some simple steps:

  • Store a couple CALayers

    in an array so I can reuse them
  • Set the pivot point of all CALayers to 0.0.
  • Draw CALayer

    objects where the object starts in a circular position
  • The layers rotate at the same angle as the circle in this position
  • Update the position and rotation of the CALayer to match the new values

Here is the piece of code I have:

lineWidth

- line width self.items

is an array containing objectsCALayer

func updateLines() {

    var space = 2 * M_PI * Double(circleRadius);
    var spaceAvailable = space / (lineWidth)

    var visibleItems = [Int]();

    var startIndex = items.count - Int(spaceAvailable);
    if (startIndex < 0) {
        startIndex = 0;
    }

    for (var i = startIndex; i < self.items.count; i++) {
        visibleItems.append(self.items[i]);
    }

    var circleCenter = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));

    /* Each line should move up and rotate accordin to this value */
    var anglePerLine: CGFloat = (360 / CGFloat(visibleItems.count)).toRadians()

    /* Starting position, 270 degrees is on top */
    var startAngle: CGFloat = CGFloat(270).toRadians();

    /* Lines default rotation, we rotate it to get the right side up */
    var lineAngle: CGFloat = CGFloat(180).toRadians();

    for (var itemIndex = 0; itemIndex < visibleItems.count; itemIndex++) {
        var itemLayer = self.itemLayers[itemIndex];
        itemLayer.opacity = 1 - ((0.9 / visibleItems.count) * itemIndex);

        /* Calculate start position of layer */
        var x = CGFloat(circleRadius) * cos(startAngle) + CGFloat(circleCenter.x);
        var y = CGFloat(circleRadius) * sin(startAngle) + CGFloat(circleCenter.y);
        var height = CGFloat((arc4random() % 80) + 10);

        /* Set position and frame of layer */
        itemLayer.frame = CGRectMake(CGFloat(x), CGFloat(y), CGFloat(lineWidth), height);
        itemLayer.position = CGPointMake(CGFloat(x), CGFloat(y));

        var currentRotation = CGFloat((itemLayer.valueForKeyPath("transform.rotation.z") as NSNumber).floatValue);
        var newRotation = lineAngle - currentRotation;

        var rotationTransform = CATransform3DRotate(itemLayer.transform, CGFloat(newRotation), 0, 0, 1);
        itemLayer.transform = rotationTransform;

        lineAngle += anglePerLine;
        startAngle += anglePerLine;
    }
}

      

The result of the first run is exactly what I want:

enter image description here

A second run through this code just doesn't update the CALayers correctly and it starts to look like this:

enter image description here

I think it has something to do with my code for updating properties location

and transform

CALayer, but whatever I do it always results in the last image.

+3


source to share


2 answers


Reply via Twitter: Frames and transforms are mutually exclusive. Happy to help. Finding my credentials for SO is more complicated.: D



+2


source


Found the answer thanks to @iosengineer on Twitter. When set position

to CALayer, you do not want to update frame

this layer, but you do want to update bounds

.



Smooth FTW animation

0


source







All Articles