Even though I have asked this question before, I would like to reach out again to clarify what I would like to accomplish with your help. I was wondering how you would create a background of and iOS application in xCode similar to the background of the Solar weather app (screenshots provided) that changes slightly over time (in a cycle). As you can see the gradient is very smooth and obviously contains more than two main points.
Any help with example or snippets of code would be greatly appreciated. Thanks Again, Ben.
What I need is:
adding a CAGradientLayer
to your view controller (or custom view), e.g.:
@property (nonatomic, retain) CAGradientLayer *gradient;
In your view controller, in viewDidLoad, create and add the gradient layer to your view:
self.gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;
gradient.colors = [NSArray arrayWithObjects:
(id)topColor.CGColor,
(id)bottomColor.CGColor,
nil];
gradient.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.7],
nil];
[self.view.layer addSublayer:self.gradient];
3a. add an NSTimer to your controller that will update self.gradient
at proper intervals by doing:
topColor = ...; bottomColor = ...;
NSArray* newColors = [NSArray arrayWithObjects:
(id)topColor.CGColor,
(id)bottomColor.CGColor,
nil];
[(CAGradientLayer *)self.layer setColors:newColors];
This will allow you to exactly decide which colour you want to use for the gradient at each step. Otherwise, you might try with an animation, like this:
3b. add the animation like this,
- (void)animateLayer... {
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[CATransaction begin];
[CATransaction setAnimationDuration:duration];
topColor = ...; bottomColor = ...;
NSArray* newColors = [NSArray arrayWithObjects:
(id)topColor.CGColor,
(id)bottomColor.CGColor,
nil];
[(CAGradientLayer *)self.layer setColors:newColors];
[CATransaction commit];
}
completion:^(BOOL b) {
[self animateLayer..];
}];
}
You might also combine 3a and 3b.
Simple working example:
.h file
@property (strong, nonatomic) CAGradientLayer *gradient;
.m file
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear: animated];
self.gradient = [CAGradientLayer layer];
self.gradient.frame = self.view.bounds;
self.gradient.colors = @[(id)[UIColor purpleColor].CGColor,
(id)[UIColor redColor].CGColor];
[self.view.layer insertSublayer:self.gradient atIndex:0];
[self animateLayer];
}
-(void)animateLayer
{
NSArray *fromColors = self.gradient.colors;
NSArray *toColors = @[(id)[UIColor redColor].CGColor,
(id)[UIColor orangeColor].CGColor];
[self.gradient setColors:toColors];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"colors"];
animation.fromValue = fromColors;
animation.toValue = toColors;
animation.duration = 3.00;
animation.removedOnCompletion = YES;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
animation.delegate = self;
// Add the animation to our layer
[self.gradient addAnimation:animation forKey:@"animateGradient"];
}
You might want to implement an additional method to shift the colors, and then reanimate the changes. But this should help you get there.