Search code examples
iosobjective-cios-animations

Change label background color using animation in iOS


I am trying to show an animated n number of level.

There is n number of levels under UIStackView.

What I want: Using animation

  • First, change the label 4's background color
  • Second, change the label 3's background color
  • Third, change the label 7's background color

.......

  • nth, change the label background color

What is the problems: Change all background color instantly without delaying.

enter image description here

@property (nonatomic, strong) IBOutletCollection(UILabel) NSArray *lblArray;



-(void)animationTestIntoLoop {

__block NSMutableArray* animationBlocks = [NSMutableArray new];
typedef void(^animationBlock)(BOOL);

// getNextAnimation
// removes the first block in the queue and returns it
animationBlock (^getNextAnimation)(void) = ^{

    if ([animationBlocks count] > 0){
        animationBlock block = (animationBlock)[animationBlocks objectAtIndex:0];
        [animationBlocks removeObjectAtIndex:0];
        return block;
    } else {
        return ^(BOOL finished){
            animationBlocks = nil;
        };
    }
};

for (UILabel *label in self.lblArray) {
    [animationBlocks addObject:^(BOOL finished){
        [UIView animateWithDuration:3 delay:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
            //my first set of animations

            label.backgroundColor = [UIColor redColor];



        } completion: getNextAnimation()];
    }];

 }

getNextAnimation()(YES);

}

Solution

  • I can't find it documented anywhere, but it appears the backgroundColor property of UILabel is not animatable. This hack appears to work, however, as long as you don't set the background color of the label view itself:

    *#import <QuartzCore/QuartzCore.h>*
        
            
    //Add this in ViewDidLoad
    
    for (UILabel *label in self.lblArray)
    {
        label.layer.backgroundColor = [UIColor whiteColor].CGColor;
    }
    
    -(void)animationTestIntoLoop
    {
        __block NSMutableArray* animationBlocks = [NSMutableArray new];
        typedef void(^animationBlock)(BOOL);
        
        // getNextAnimation
        // removes the first block in the queue and returns it
        animationBlock (^getNextAnimation)(void) = ^{
            
            if ([animationBlocks count] > 0){
                animationBlock block = (animationBlock)[animationBlocks objectAtIndex:0];
                [animationBlocks removeObjectAtIndex:0];
                return block;
            } else {
                return ^(BOOL finished){
                    animationBlocks = nil;
                };
            }
        };
        
        for (UILabel *label in self.lblArray)
        {
            [animationBlocks addObject:^(BOOL finished){
                
                [UIView animateWithDuration:2.0 animations:^{
                    label.layer.backgroundColor = [UIColor redColor].CGColor;
                } completion:getNextAnimation()];
            }];
        }
        getNextAnimation()(YES);
    }