Отслеживание анимации ядра - PullRequest
12 голосов
/ 25 ноября 2010

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

Я написал функцию для создания CGPath, которая соединяет два круга с четырехугольной формой. Я заполняю этот путь прозрачным CALayer, который охватывает весь экран. Поскольку слой находится за двумя круговыми UIViews, он, кажется, соединяет их.

Наконец, два UIViews анимированы с использованием Core Animation. положение и размер обоих кругов изменяются во время этой анимации.

Пока что единственный метод, с которым мне удалось добиться успеха, - это прерывать анимацию через регулярные промежутки времени, используя NSTimer, затем заново вычислять и рисовать луч, основываясь на расположении круга представленияLayer. Однако четырехугольник отстает от кругов при ускорении анимации.

Есть ли лучший способ сделать это с помощью Core Animation? Или я должен избегать Core Animation и реализовывать свою собственную анимацию, используя NSTimer?

Ответы [ 2 ]

13 голосов
/ 08 декабря 2010

Я столкнулся с подобной проблемой. Я использовал слои вместо видов для анимации. Вы можете попробовать что-то вроде этого.

  1. Нарисуйте каждый элемент в виде CALayer и включите их в качестве подслоев для слоя вашего контейнера UIVIew. UIViews легче анимировать, но у вас будет меньше контроля. Обратите внимание, что для любого вида вы можете получить его слой с помощью [view layer];
  2. Создайте пользовательский подслой для вашего четырехугольника. Этот слой должен иметь свойство или несколько свойств, которые вы хотите анимировать для этого слоя. Давайте назовем это свойство «customprop». Поскольку это пользовательский слой, вы хотите перерисовать каждый кадр анимации. Для свойств, которые вы планируете анимировать, ваш пользовательский класс слоя должен возвращать YES needsDisplayForKey :. Таким образом вы гарантируете, что - (void) drawInContext: (CGContextRef) theContext вызывается в каждом кадре.
  3. Поместите все анимации (и круги, и квад) в одну транзакцию;

Для кругов вы, вероятно, можете использовать CALayers и установить контент, если это изображение, стандартным способом:

layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage;

Теперь для четверного слоя создайте подкласс CALayer и реализуйте его следующим образом:

- (void)drawInContext:(CGContextRef)theContext{
  //Custom draw code here
}   
+ (BOOL)needsDisplayForKey:(NSString *)key{
   if ([key isEqualToString:@"customprop"])
      return YES;
    return [super needsDisplayForKey:key];
}   

Транзакция будет выглядеть так:

[CATransaction begin];
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"customprop"];

theAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1000, 1000)];
theAnimation.duration=1.0;
theAnimation.repeatCount=4;
theAnimation.autoreverses=YES;
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
theAnimation.delegate = self;
[lay addAnimation:theAnimation forKey:@"selecting"];

[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
                     forKey:kCATransactionAnimationDuration];
circ1.position=CGPointMake(1000, 1000);
circ2.position=CGPointMake(1000, 1000);
[CATransaction commit];

Теперь все процедуры розыгрыша будут происходить одновременно. Убедитесь, что ваш drawInContext: реализация быстрая. В противном случае анимация будет отставать.

После добавления каждого подслоя в слой UIViews не забудьте вызвать [layer setNeedsDisplay]. Он не вызывается автоматически.

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

1 голос
/ 30 ноября 2010

Если вам нужно найти текущее видимое состояние слоев, вы можете вызвать -presentationLayer для соответствующего CALayer, и это даст вам слой, который приближен к уровню, используемому для рендеринга.Заметьте, что я сказал, что приближенный - это не гарантирует полной точности.Однако это может быть достаточно для ваших целей.

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