2010-12-10 4 views
0

я видел некоторый код, который удаляет данный слой от его superlayer, выполнив следующие действия:Объем блока CATransaction

void RemoveImmediately(CALayer *layer) { 
    [CATransaction flush]; 
    [CATransaction begin]; 
    [CATransaction setValue:(id)kCFBooleanTrue 
        forKey:kCATransactionDisableActions]; 
    [layer removeFromSuperlayer]; 
    [CATransaction commit]; 
} 

Я написал метод, который изменяет положение данного слоя в анимированный используя CAKeyframeAnimation, который выглядит следующим образом:

- (void)animateMovingObject:(NXUIObject*)obj 
      fromPosition:(CGPoint)startPosition 
      toPosition:(CGPoint)endPosition 
       duration:(NSTimeInterval)duration {  

    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 
    pathAnimation.calculationMode = kCAAnimationPaced; 
    pathAnimation.duration = duration; 

    CGMutablePathRef curvedPath = CGPathCreateMutable(); 
    CGPathMoveToPoint(curvedPath, NULL, startPosition.x, startPosition.y); 
    CGPathAddCurveToPoint(curvedPath, NULL, 
         startPosition.x, endPosition.y, 
         startPosition.x, endPosition.y, 
         endPosition.x, endPosition.y); 
    pathAnimation.path = curvedPath; 
    [obj addAnimation:pathAnimation forKey:@"pathAnimation"]; 
    CGPathRelease(curvedPath); 
} 

Дознание, все в порядке. Теперь предположим, что у меня в моем приложении «мастер-слой», который имеет 3 подслоя. Я хочу, чтобы первые два подслова были перемещены в другое место, а последнее - для удаления. Так что я сделал следующее:

CALayer obj1 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj1]; 
[self animateMovingObject:obj1 
      fromPosition:CGPointMake(0.0, 0.0) 
       toPosition:CGPointMake(100.0, 100.0) 
       duration:2.0]; 

CALayer obj2 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj2]; 
[self animateMovingObject:obj2 
      fromPosition:CGPointMake(0.0, 0.0) 
       toPosition:CGPointMake(150.0, 100.0) 
       duration:2.0]; 

CALayer obj3 = ... // set up layer and add as sublayer 
[self.masterLayer addSublayer:obj3]; 
// ... 
RemoveImmediately(obj3);  // This removes the two previous animations too 
//[obj3 removeFromSuperlayer]; // This just removes obj3, the previous animations works 

Обратите внимание, что, если я позвоню RemoveImmediately(), даже проходя obj3 в качестве аргумента я не могу увидеть первые два слоя анимируемого. Однако, если я удалю obj3, просто позвонив removeFromSuperlayer, первые два слоя будут анимированы в обычном режиме. Похоже, что блок CATransaction отменяет все выполняемые анимации, даже те, которые были созданы с помощью CAKeyframeAnimation.

Что мне счесть?

Спасибо заранее.

ответ

2

Сфера действия CATransaction должна быть только между линиями [CATransaction begin] и [CATransaction commit].

Кроме того, в этом коде вам не нужен [CATransaction flush]. Apple обычно рекомендует не принудительно выполнять отложенные транзакции по соображениям производительности, а транзакция, которую вы настраиваете, не должна влиять на ожидающие анимации.

Я предполагаю, что это странное поведение по-прежнему связано с тем, что вы задали в своем previous question, где три анимации каким-то образом мешают друг другу. Как я прокомментировал там, это ведет себя, как три анимации добавляются в один слой, а не три независимых. Я проверил бы и убедился бы, что не было возможности этого происшествия (скрещенные указатели и т. Д.).

+0

Спасибо, я показал мне способ добиться успеха! Проблема заключалась в методе «флеш». Я удалил его, и теперь я вижу, что все анимации работают нормально. Единственное, что объединяет «obj1», «obj2» и «obj3», это то, что они являются подслоями «masterLayer», поэтому не было пересекающихся указателей или какой-либо анимации, мешающей другому. Вызвав метод «flush», предыдущие анимации были остановлены (метод делегата «animationDidStop: finished:» завершенный аргумент возвратил NO, указав, что они были вручную остановлены (что, как я думаю, произошло, когда был вызван метод «flush»)). –

+0

Хотя это сработало, я попытался понять, что в документации говорится о методе flush (http://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CATransaction_class/Introduction/Introduction.html#//apple_ref/ occ/clm/CATransaction/flush), и мне все еще не ясно, почему это приводит к тому, что мои явные анимации будут «остановлены». –

+0

@Eduardo - Да, у меня также были проблемы с '[CATransaction flush]' срыв анимации, потому что он мешает нормальному конвейеру рендеринга Core Animation. Только однажды мне это было нужно для чего-то, и даже тогда я нашел способ перепроектировать то, что я делал, чтобы в конечном итоге удалить этот звонок. –

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