We used DrawingHelpers from last time. We'll use them again here:
// DrawingHelpers.h
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor);
void drawGlossyGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor);
// DrawingHelpers.m
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = @[ (__bridge id)(startColor), (__bridge id)endColor ];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CFRelease(gradient);
CFRelease(colorSpace);
}
void drawGlossyGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor) {
drawLinearGradient(context, rect, startColor, endColor);
CGColorRef shineStart = [[UIColor colorWithWhite:0.9 alpha:0.35] CGColor];
CGColorRef shineEnd = [[UIColor colorWithWhite:0.9 alpha:0.1] CGColor];
CGRect shineRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height / 2.0f);
drawLinearGradient(context, shineRect, shineStart, shineEnd);
}
This is very simple, just change the class of the view in your XIB to GradientView. The GradientView class looks like this:
// GradientView.m
#import "GradientView.h"
#import "DrawingHelpers.h"
@implementation GradientView
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef color1 = [[UIColor colorWithWhite:0.35 alpha:1.0f] CGColor];
CGColorRef color2 = [[UIColor colorWithWhite:0.15 alpha:1.0f] CGColor];
drawLinearGradient(context, self.bounds, color1, color2);
}
@end
Finally, we want to show a shape in the middle of the screen. Take a look at the XIB provided in the sample code to see how the slider is wired up to this view.
// PolygonView.h
@interface PolygonView : UIView
@property (nonatomic, assign) NSUInteger numberOfSides;
@property (nonatomic, retain) UIColor *strokeColor;
@property (nonatomic, retain) UIColor *fillColor;
@end
// PolygonView.m
#import "PolygonView.h"
#import "DrawingHelpers.h"
#define MIN_NUM_SIDES 3
#define MAX_NUM_SIDES 100
@implementation PolygonView
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit {
self.backgroundColor = [UIColor clearColor];
self.numberOfSides = MIN_NUM_SIDES;
self.fillColor = [UIColor redColor];
self.strokeColor = [UIColor whiteColor];
}
- (void)setNumberOfSides:(NSUInteger)numberOfSides {
if (numberOfSides < MIN_NUM_SIDES) {
numberOfSides = MIN_NUM_SIDES;
}
if (numberOfSides > MAX_NUM_SIDES) {
numberOfSides = MAX_NUM_SIDES;
}
_numberOfSides = numberOfSides;
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
if (self.numberOfSides == 0) {
return;
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat radius = floorf( 0.9 * MIN(self.bounds.size.width, self.bounds.size.height) / 2.0f );
CGContextSetFillColorWithColor(context, [self.fillColor CGColor]);
CGContextSetStrokeColorWithColor(context, [self.strokeColor CGColor]);
CGContextSetLineWidth(context, 6.0);
CGContextSetLineCap(context, kCGLineCapRound);
CGMutablePathRef path = CGPathCreateMutable();
CGFloat startingAngle = 2 * M_PI / self.numberOfSides / 2.0f;
for (int n = 0; n < self.numberOfSides; n++) {
CGFloat rotationFactor = ((2 * M_PI) / self.numberOfSides) * (n+1) + startingAngle;
CGFloat x = (self.bounds.size.width / 2.0f) + sin(rotationFactor) * radius;
CGFloat y = (self.bounds.size.height / 2.0f) + cos(rotationFactor) * radius;
if (n == 0) {
CGPathMoveToPoint(path, NULL, x, y);
} else {
CGPathAddLineToPoint(path, NULL, x, y);
}
}
CGPathCloseSubpath(path);
CGContextSaveGState(context);
CGContextSetShadow(context, CGSizeMake(0, 10), 2.0);
CGContextAddPath(context, path);
CGContextFillPath(context);
CGContextAddPath(context, path);
CGContextClip(context);
drawLinearGradient(context, self.bounds, [self.fillColor CGColor], [[UIColor blueColor] CGColor]);
CGContextRestoreGState(context);
CGContextAddPath(context, path);
CGContextStrokePath(context);
CFRelease(path);
}
@end