CABasicAnimation оживляет все, когда нужно оживить только одну вещь - PullRequest
1 голос
/ 22 июня 2010

Я сделал несколько маленьких отдельных картинок, каждая с отдельным CALayer, и они должны были появляться и исчезать асинхронно с разной скоростью.У каждого есть подслой фона и подслой заполнения.Таймер работает в фоновом режиме, чтобы оживить каждого из них в определенные моменты.Для текущего поведения программы, вместо того, чтобы анимировать каждый отдельный, вместо этого она анимирует весь экран вокруг нее.Не могли бы вы помочь мне сделать так, чтобы он одновременно анимировал только одно изображение?

РЕДАКТИРОВАТЬ: Я должен был быть более ясным.Время не проблема.Прежде чем я переключился на CoreAnimation, эти изображения правильно анимировались в подходящее время.Но главная проблема здесь в том, что когда я говорю анимации одному изображению, весь экран, включая фоновую часть экрана за пределами всех изображений, анимируется.

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

- (CALayer *) createImageLayer:(CGPoint)orig Center:(CGPoint)pos {
    CALayer *parentLayer = [self layer];
    CALayer *childLayer1 = [CALayer layer];
    childLayer1.bounds = CGRectMake(0, 0, 40.0f, 40.0f);
    childLayer1.position = pos;
    CALayer *childLayer2 = [CALayer layer];
    childLayer2.bounds = CGRectMake(0, 0, 40.0f, 40.0f);
    childLayer2.position = pos;

    float components[4] = {1.0, 1.0, 1.0, 1.0};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGColorRef whiteColor = CGColorCreate( colorSpace, components);

    childLayer1.backgroundColor = whiteColor;
    childLayer2.backgroundColor = whiteColor;

    UIImage *childImage = [UIImage imageNamed:@"back.png"];
    UIImage *childImage2 = [UIImage imageNamed:@"fill.png"];

    CGImageRef imageRef = [childImage CGImage];
    CGImageRef imageRef2 = [childImage2 CGImage];

    childLayer1.contents=(id)imageRef;
    childLayer2.contents=(id)imageRef2;

    [parentLayer addSublayer:childLayer1];
    [parentLayer addSublayer:childLayer2];

    CGColorSpaceRelease(colorSpace);
    CGColorRelease(whiteColor);

    return parentLayer;
}

Код для передачи его в анимацию.Объект изображения получает указание добавить анимацию к члену своего слоя.

- (void) fadeAnimation:(ImageClass *)image {
    CABasicAnimation *theAnimation;

    theAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
    theAnimation.duration=1.0; // fixed duration for now
    theAnimation.repeatCount=1;
    theAnimation.autoreverses=YES;
    theAnimation.fromValue=[NSNumber numberWithFloat:1.0];
    theAnimation.toValue=[NSNumber numberWithFloat:0.0];
    [image.myLayer addAnimation:theAnimation forKey:@"animateOpacity"];
}

1 Ответ

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

Во-первых, ваш код может быть значительно сжат, что облегчит чтение:

- (CALayer *) createImageLayer:(CGPoint)orig Center:(CGPoint)pos 
{    
    CALayer *childLayer1 = [CALayer layer];
    childLayer1.bounds = CGRectMake(0, 0, 40.0f, 40.0f);
    childLayer1.position = pos;

    CALayer *childLayer2 = [CALayer layer];
    childLayer2.bounds = CGRectMake(0, 0, 40.0f, 40.0f);
    childLayer2.position = pos;

    childLayer1.backgroundColor = [[UIColor whiteColor] CGColor];
    childLayer2.backgroundColor = [[UIColor whiteColor] CGColor];

    childLayer1.contents=(id)[[UIImage imageNamed:@"back.png"] CGImage];
    childLayer2.contents=(id)[[UIImage imageNamed:@"fill.png"] CGImage];

    [[self layer] addSublayer:childLayer1];
    [[self layer] addSublayer:childLayer2];

    return parentLayer;
}

Далее, я бы предложил, чтобы вместо создания таймера вы просто использовали -performSelector: withObject: afterDelay . Затем вы можете добавить все свои анимации одновременно, просто пошатнув параметр afterDelay. Как то так:

int i = 0;
for (i = 0; i < 10; ++i)
{
    [self performSelector:@selector(fadeAnimation:) 
               withObject:images[i] 
               afterDelay:(CGFloat)i];
}

Где images - это массив C ваших объектов ImageClass. Конечно, вам не нужно использовать массив C. Вы можете использовать NSArray, но вам все еще нужен счетчик для вашего параметра afterDelay. Это заставит ваши анимации возникать каждую секунду. Я не совсем уверен, что вы хотите, поэтому я просто показываю это в качестве примера.

Есть и другие способы сделать то, что вы просите, с помощью Core Animation. Вы можете посмотреть на группировку анимации и свойство beginTime , но я думаю, что метод -peformSelector, который я упоминал выше, является путем меньшего сопротивления.

С наилучшими пожеланиями

...