Как применить сложные изменения преобразования CALayer?

Мне нужна сложная непрерывная анимация UIView это включает в себя настройку CATransform3D свойства поворота и перемещения, которые необходимо рассчитать, поэтому стандартная анимация не предусмотрена.

Я обратился к использованию CALayer анимация. И есть это:

self.displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(update:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

- (void)update:(CADisplayLink*)sender
{
    CGFloat elapsedTime = sender.timestamp - self.lastTimestamp;
    self.lastTimestamp = sender.timestamp;

    self.rotation += elapsedTime * 0.1;  // Factor determines speed.

    // This is just example for SO post; the real animation is more complicated!
    CATransform3D transform;
    transform = CATransform3DMakeRotation(self.rotation, 1.0, 0.0, 0.0);
    self.imageLayer.transform = transform;
}

Вот self.imageLayer это CALayer чья contents был установлен с изображением и добавлен в качестве подслоя для моего базового вида.

Он вращается "немного", но не непрерывно, иногда кажется, что он немного останавливается или вращается назад.

Кажется, что назначение нового transform довольно часто не имеет никакого эффекта, потому что self.rotation значение увеличивается намного больше. Добавление [self setNeedsDisplay] не помогло.

Я не много сделал с CALayerНо я думаю, что мне не хватает чего-то очень простого. Некоторое время пытался найти его, но все найденные примеры кажутся слишком далекими от того, что я хочу.

1 ответ

Решение

Когда вы создаете свой собственный слой и затем изменяете его свойства, он неявно анимирует их (см. "Анимация простых изменений свойств слоя"). Вы не видите ожидаемых изменений, потому что базовая анимация анимирует изменения, а не применяет их мгновенно.

Вам нужно отключить неявную анимацию. Есть несколько способов отключить его; см. "Изменение поведения слоя по умолчанию". Или переполнение стека поиска для "отключения неявной анимации". Вот один из способов:

NSDictionary *actions = @{ @"transform": [NSNull null] };
self.imageLayer.actions = actions;

Просто сделайте это один раз, где вы создаете imageLayer,

Другие вопросы по тегам