2014-12-18 3 views
2

Я пытаюсь обновить текущее вращение (а иногда и положение) CALayer.Обновить поворот CALayer

То, что я пытаюсь в пару простых шагов:

  1. магазин пару CALayers в массиве, так что я могу использовать их
  2. Установите точку привязки всех CALayers 0,0 ,
  3. Draw CALayer объектов, где объект начинается в положении по окружности
  4. слои повернуты на тот же угол, что и круг в этом положении
  5. обновления положения и поворот CALayer, чтобы соответствовать новым значениям

Вот кусок кода у меня есть:

lineWidth ширина линии
self.items представляет собой массив, содержащий CALayer объекты

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; 
    } 
} 

Результат первого запуска именно так, как я хочу, чтобы это было:

enter image description here

Второй прогон через этот код просто не обновляет CALayers правильно, и он начинает чтобы выглядеть следующим образом:

enter image description here

Я думаю, что он должен делать с моим кодом, чтобы обновить т он location и transform свойства CALayer, но что бы я ни делал, это всегда приводит к последнему изображению.

+0

Ahhh !! Отличный материал, сделанный вами. Глупые предложения. Вы можете использовать образы и оживлять их, чтобы они выглядели как вращающиеся. – Kampai

+0

Это на самом деле график со случайными линиями длины. И я хочу повторно использовать CALayers, которые у меня уже есть, чтобы иметь возможность оживить их. –

ответ

2

Ответил через Twitter: установка фреймов и преобразование является взаимоисключающим. Рад был помочь. Поиск моих учетных данных для SO более сложный. : D

0

Нашел ответ благодаря @iosengineer на Twitter. При установке position на CALayer вы не хотите обновлять frame уровня, но вы хотите обновить bounds.

Smooth animation FTW

+0

LOL. Похоже на что-то острое, что я не хочу держать. – iosengineer

Смежные вопросы