После анимации позиция просмотра сбрасывается

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

CABasicAnimation *animation;
animation = [CABasicAnimation animationWithKeyPath:@"position"];
[animation setDelegate:self];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(self.view.layer.position.x, 0 - self.view.bounds.size.height / 2)];
animation.fromValue = [NSValue valueWithCGPoint:self.view.layer.position];
animation.autoreverses = NO;
animation.repeatCount = 0;
animation.duration = 0.25;
animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
[self.view.layer  addAnimation:animation forKey:@"moveX"];

Что отлично оживляет вид. Но после завершения анимации мой вид снова появляется. Итак, я добавил эту строку:

[self.view removeFromSuperview];

Что удаляет вид, но без анимации. Поэтому я решил добавить этому делегату код удаления:

-(void) animationDidStop:(CAAnimation *) animation finished:(bool) flag

Итак, теперь анимация работает, представление исчезает, но иногда я вижу, что представление появляется и исчезает быстрее, как после анимации, появляется представление, затем вызывается делегат animationDidStop и представление исчезает, очевидно, это ужасно . Что я делаю неправильно?


person carlos    schedule 22.10.2008    source источник


Ответы (6)


Что ж, согласно образцу Apple «MoveMe», это (deletedOnCompletion) должно работать, однако, похоже, это не так.

Итак, добавьте эти строки после вашего кода:

[self.view.layer  addAnimation:animation forKey:@"moveX"];
self.view.layer.position = [animation.toValue CGPointValue];

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

person Ben Gottlieb    schedule 22.10.2008
comment
Почему я этого не увидел? Спасибо, это решило мою проблему. Я думаю, что это ошибка, я не должен этого делать, но, по крайней мере, это работает. - person carlos; 23.10.2008
comment
Я согласен, или мы что-то упускаем, так как это ДЕЙСТВИТЕЛЬНО работает в образце. Думаю, нужно больше экспериментировать! - person Ben Gottlieb; 23.10.2008

Возможно, вы захотите установить эти свойства. Они вызывают сохранение презентации в конце анимации.

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

Затем можно использовать метод animationDidStop: для удаления представления в конце анимации:

-(void) animationDidStop:(CAAnimation *) animation finished:(bool) flag {
    if (animation == [containerView.layer animationForKey:@"moveX"]) {
        // remove view here, add another view and/or start another transition
    }
}
person Community    schedule 30.10.2008
comment
+1! Пытался установить removedOnCompletion, но кубиков нет. Однако добавление fillMode = kCAFillModeForwards дополнительно исправило это. Здорово! - person August Lilleaas; 26.09.2010
comment
Когда CA начинает анимацию слоя, он делает копию, а затем постепенно устанавливает свойства на нем и перерисовывает его. Этот метод действительно работает, но он продолжает анимировать слой презентации вечно (с одним и тем же значением снова и снова). Если вы хотите, чтобы уровень представления умер, вы можете связать установщик в презентации с установщиком на уровне модели. Один из способов сделать это - использовать указатель на объект для вашего свойства, например NSValue, а не примитив. Затем, когда уровень представления устанавливает свойство, слой модели также подберет его. - person AlexChaffee; 06.04.2013
comment
Обратите внимание: я пробовал этот метод для своей анимации цвета фона, но иногда он возвращал исходный цвет мерцанию. Удивительно, но использование решения Бена сработало (пока мерцания нет). - person lindon fox; 03.01.2015
comment
Этот метод полезен, когда анимация является интерактивной, вы можете получить положение текущего слоя и выполнить дальнейшую анимацию. Но когда он не интерактивен, метод @Ben проще. - person Nickolas; 02.04.2015
comment
У этого выпуска должна быть зеленая галочка! - person ReduxDJ; 11.08.2015

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

CAAnimationGroup *animGroup = [CAAnimationGroup animation];

// MAKE SURE YOU HAVE THESE TWO LINES.
animGroup.removedOnCompletion = NO;
animGroup.fillMode = kCAFillModeForwards;

animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, nil];
animGroup.duration = tAnimationDuration;
[tImageView.layer addAnimation:animGroup forKey:nil];
person FreeAsInBeer    schedule 25.02.2013

Этот тоже меня укусил. Вы хотите установить для флага removeOnCompletion анимации значение NO. По умолчанию установлено ДА, что означает, что после завершения анимации она удаляется, а представление возвращается в исходное состояние.

person Ben Gottlieb    schedule 22.10.2008
comment
То же самое и здесь, я пробовал тот же результат. Я вызываю этот код из той же точки зрения, когда они нажимают кнопку. - person carlos; 23.10.2008

Установка вида на скрытый, как предлагает Роб, должна сделать это.

Что касается свойств свойств, я бы придерживался стиля ObjC 2.0, который уже есть в вашем коде.

set.view.hidden = YES;
person danimal    schedule 22.10.2008

Можете ли вы установить для скрытого представления значение ДА?

Думаю было бы:

self.view.hidden = YES;

Но это могло быть:

[self.view setHidden:YES];

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

person Rob Drimmie    schedule 22.10.2008
comment
Я сделал это, но получил те же результаты. - person carlos; 23.10.2008
comment
Это точно так же. - person Ricardo; 12.04.2016