Настройка layer.transform мигает слой в конечной позиции, а затем анимирует его из текущей позиции - PullRequest
1 голос
/ 17 июня 2010

Иногда при установке layer.transform в новое преобразование я вижу, что слой мигает в своем законченном местоположении, а затем анимирует из своего текущего местоположения в свое законченное местоположение.

Я не знаю, связано ли это, но в то же время я устанавливаю преобразование sublayerTransform для суперслоя слоя.

Я действительно понятия не имею, почему это происходит, любые мысли будут оценены.

Спасибо.

Обновление

Когда я удаляю преобразование подслоя, такое поведение не происходит.

Это мои начальные настройки.

Я избегаю неявных действий с моим подслоем Transform с:

self.actions = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"sublayerTransform"];

Этот метод преобразует отдельный слой

- (void)setSelectedCover:(int)cover{    
    selectedCover = cover;

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];

    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:0.3f]
                    forKey:kCATransactionAnimationDuration];

    coverLayer.transform = flippedUpTransform;
    [CATransaction commit];
}

Этот метод создает эффект прокрутки (я знаю, что есть более удобные способы прокрутки, но это пока лучшая реализация для моих нужд), этот метод вызывается всякий раз, когда палец движется по экрану.

- (void)setScrollOffset:(float)offset absolute:(BOOL)absolute animated:(BOOL)animated{
     CATransform3D aSublayerTransform = self.sublayerTransform;
     scrollOffset = aSublayerTransform.m41;

     if (absolute) {
        scrollOffset = offset;
     }else {
        scrollOffset += offset;
     }

     [self setValue:[NSNumber numberWithInt:scrollOffset] forKeyPath:@"sublayerTransform.translation.x"];
}

Также. Я могу воспроизвести это только на устройствах 2-го поколения (не на 3-м), так что это заставляет меня думать, что это отчасти проблема производительности устройства, но мне все еще нужно обойти это.

Я рассмотрел использование CABasicAnimation (явные анимации), например, так:

  - (void)setSelectedCover:(int)cover{  
    selectedCover = cover;

    CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:flippedUpTransform];
    animation.duration = 0.3f;

        [coverLayer addAnimation:animation forKey:@"transform"];
   }

Это на самом деле работает очень хорошо, без мерцания! единственная проблема сейчас - заставить его остаться.

Итак, я добавил это к анимации:

animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

Это фактически заставило его остаться в конце анимации, но Я думаю, что для любого, кто работает над аналогичной задачей, важно знать, что добавление этих двух строк только делает слой презентации неактивным, он не сохраняется это в слой модели. В моем случае у меня есть дополнительные преобразования для слоя под рукой, если я хочу преобразовать снова, говоря, что layer.transform = newtransform и модель никогда не изменялась, мой слой вернется к своему исходное преобразование до того, как я выполнил явную анимацию.

Так что я подумал, что у меня есть довольно хорошее решение проблемы с сохранением преобразования. Я добавил:

animation.delegate = coverLayer.delegate;

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

Это то, что я реализовал в делегате.

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{

   if (flag) {

    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue
                     forKey:kCATransactionDisableActions];
    cover.transform = flippedUpTransform;
    [CATransaction commit];
    [cover performSelector:@selector(removeAllAnimations) withObject:nil afterDelay:0.2];

   }
}

Если анимация завершена успешно, я беру готовое преобразование и применяю его к самой модели

Вскоре после удаления явной анимации, поскольку при установке других преобразований запускается последняя добавленная анимация.

Это работает.

Если анимация не завершилась, я ничего не делаю. Мне не нужно обновлять модальный слой, потому что прерванная анимация должна отвечать за то, где он остановился, и за то, чтобы презентация сохранялась.

Проблема в том, что отложенные вызовы всегда включены. Это не так. Он достаточно держит это вместе, но иногда все может выглядеть немного не так. В конце концов, я приму это решение, если не смогу исправить его. Это не так гладко ...

Ответы [ 2 ]

0 голосов
/ 23 июня 2010

Обновление iOS4 решает эту проблему.

0 голосов
/ 18 июня 2010

Было бы полезно, если бы вы показывали код, который вы используете, но иногда я видел мерцание, когда код анимирует свойство (преобразование в вашем случае), а затем устанавливает свойство в последующем цикле выполнения.Происходит то, что к нему (слою) добавляется анимация дважды.Просто помните, что внесение изменений в свойство некорневого слоя напрямую (неявно) будет анимировать это свойство, если вы не отключите анимацию.Также помните, что анимация свойства не устанавливает его автоматически.Если вы используете явную анимацию, убедитесь, что когда вы добавляете анимацию в слой, вы используете «преобразование» в качестве ключа - что-то вроде:

CABasicAnimation *transformAnim = [CABasicAnimation 
                                         animationForKey:@"transform"];
[transformAnim setToValue:CATransform3DMake...];
[transformAnim setDuration:...]; // etc. etc.

// This next line actually sets the transform
[transformLayer setTransform:CATransform3DMake...];
// This overrides the default animation for animating the transform
[transformLayer addAnimation:transformAnim forKey:@"transform"];

Не уверен, что вы используете явную анимацию,но вот что пришло в голову.

Кроме того, вы sublayerTransform может повлиять на это.Что происходит, когда вы это комментируете?Это может помочь, если вы обновите свой вопрос некоторым кодом.

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...