CABasicAnimation анимира всичко, когато трябва да анимира само едно нещо

Направих куп малки отделни снимки, всяка с отделен 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"];
}

person William    schedule 22.06.2010    source източник


Отговори (1)


Първо, вашият код може да бъде значително съкратен, което ще улесни четенето му:

- (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, който споменах по-горе, е път с по-малко съпротивление.

С Най-Добри Пожелания

person Matt Long    schedule 22.06.2010
comment
Благодаря ти за помощта. Основният проблем, който получавам, е, че когато мисля, че казвам на всяко отделно изображение да направи избледняваща анимация, като [self fadeAnimation:myImage], то вместо това прави анимацията на целия екран, но не и на изображението. Времето всъщност не е проблем за мен, но бих могъл да изпробвам вашето предложение, тъй като това изглежда по-подходящо за моите цели от таймер. - person William; 23.06.2010