Wednesday, August 4, 2010

Designing beautiful gradient buttons in Cocoa with Core Graphics- Part 1

Ok, Let's start with the final result - What I want to talk about is how to design and code beautiful gradient buttons with Cocoa and core graphics - Here's a screenshot of the final result we used in our game Deca Sudoku Version 2.0:
I'll try to keep the flow the same as it was when we were designing this interface.
We started off with photoshop - designing the gradient squares.
Step 1 - Color gradient - for this square we used this cool green gradient - if you want to reproduce it it's R:22 G:79 B:2 for the dark color (or H:104 S:98 B:31) and R:52 G:157 B:15 for the light color (or H:104 S:98 B:62) - Actually it's much easier to think of it in the HSB palette because you only have to make the color a bit less saturated and brighter to get the end result.

Step 2 - We start designing a single square - For this we've put four layers with different blending modes together. Here are the exact values if you want to recreate it:
Step 3 - We add inner gradient to tie it all together and a stoke on the inside:

Step 4 - Now we're done with the first tile gradient, we change the base gradient values for the second one and make two tile files: Tile1.png, Tile2.png (don't forget to pngcrush them).
So let's load it up in code - We used a bounce animation in our code with an internal animation framework that we built, but you can get the same result - now easier than ever - using UIView animation with blocks (iOS 4 and above).
So your code might look something like this:

- (void) addTiles{
UIImage *tile1Image = [UIImage imageNamed:@"tile1"];
UIImage *tile2Image = [UIImage imageNamed:@"tile2"];
CGSize  imageSize = tile1Image.size;
for (NSInteger iter=0;iter<9;iter++){
UIImageView *tileImageView = [[UIImageView alloc] initWithFrame:
  CGRectMake(XPOS+(iter%3)*imageSize.width
    YPOS+(iter/3)*imageSize.height
    imageSize.width
    imageSize.height)];
[tileImageView setImage:(iter%2==0) ? tile1Image : tile2Image];
[tileImageView setHidden:YES];
[self.view addSubview:tileImageView];
[self animateTiles:tileImageView];
[tileImageView release];
}
}
To bounce animate the views you can nest three UIView animates in block completion:


- (void) animateTiles:(UIImageView*)tileToAnimate{
[tileToAnimate setTransform:CGAffineTransformMakeScale(0.001, 0.001)];
[tileToAnimate setHidden:NO];
[UIView animateWithDuration:ANIMATION_DURATION*0.45 
animations:^{[tileToAnimate setTransform:CGAffineTransformMakeScale(1.1, 1.1)];} 
completion:^(BOOL finished) {
[UIView animateWithDuration:ANIMATION_DURATION*0.3 
  animations:^{[tileToAnimate setTransform:CGAffineTransformMakeScale(0.9, 0.9)];} 
  completion:^(BOOL finished) {
  [UIView animateWithDuration:ANIMATION_DURATION*0.25 
  animations:^{[tileToAnimate setTransform:CGAffineTransformMakeScale(1.0, 1.0)];}];
  }];
}];
}
Any you're done, for now :)
The end result might look like this:


So what's in the next part? Well replace the static gradient background with a programmatic color and use "drawAtPoint" blend modes to create the same effect we did in Photoshop - programmatically.

Hope this was useful to you, comments will be welcomed :)

0 comments:

Post a Comment