Once of the first pieces of iPhone code I wrote was the following to display a clock, made of leaves.
A clock is created from three leaves, hours, minutes and seconds, and we have a single leaf image, which is drawn with different scaling, opacity etc., to give the appearance of a clock.
The UIView below draws a clock in the centre of the view, using translation and scaling to put the leaves in the right place. The CTM is saved and restored to save repeated translations.
You might want to look and see if it helps you with how you might deal with coordinate systems and rotating.
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame])
{
// Initialization code
self.minutes = 49;
self.seconds = 0;
// clear to transparent
self.clearsContextBeforeDrawing = YES;
self.backgroundColor = [UIColor clearColor];
[self tick:nil];
}
return self;
}
- (void)tick:(NSTimer *)timer
{
// get time
NSDate * time = [NSDate date];
NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents * comp = [gregorian components:NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:time];
// update the time
self.seconds = [comp second];
self.minutes = [comp minute];
self.hours = [comp hour];
// redisplay
[self setNeedsDisplay];
}
- (float)toRadians:(float)deg
{
return deg * 3.14/180.0;
}
- (void)drawClock:(CGPoint)pos hours:(NSInteger)theHours minutes:(NSInteger)theMinutes seconds:(NSInteger)theSeconds
{
UIImage * leaf = [UIImage imageNamed:@"leaf.png"];
// context
CGContextRef myContext = UIGraphicsGetCurrentContext();
// save original state
CGContextSaveGState(myContext);
// set alpha and move it to centre of clock
CGContextSetAlpha(myContext, 0.8);
CGContextTranslateCTM (myContext, pos.x, pos.y);
// save centred state
CGContextSaveGState(myContext);
// rotate and translate the hour 'hand'
CGContextRotateCTM (myContext, [self toRadians:(theHours-3.0+theMinutes/60.0)*360/12.0 - 10] );
CGContextTranslateCTM (myContext, -5, -[leaf size].height/12);
// draw the hour hand and restore to translated
CGContextDrawImage(myContext, CGRectMake(0, 0, [leaf size].width/6, [leaf size].height/6), [leaf CGImage]);
// restore centred state and resave
CGContextRestoreGState(myContext);
CGContextSaveGState(myContext);
// rotate and transform the minute 'hand'
CGContextRotateCTM (myContext, [self toRadians:((theMinutes-15)*360.0 /60.0) - 10]);
CGContextTranslateCTM (myContext, -5, -[leaf size].height/10);
// draw the minute hand and restore original context
CGContextDrawImage(myContext, CGRectMake(0, 0, [leaf size].width/5, [leaf size].height/5), [leaf CGImage]);
// restore centred state
CGContextRestoreGState(myContext);
// rotate and transform the second 'hand'
CGContextSetAlpha(myContext, 0.5);
CGContextRotateCTM (myContext, [self toRadians:((theSeconds-15)*360 /60.0) - 10]);
CGContextTranslateCTM (myContext, -5, -[leaf size].height/10);
// draw the second hand and restore original context
CGContextDrawImage(myContext, CGRectMake(0, 0, [leaf size].width/5, [leaf size].height/5), [leaf CGImage]);
CGContextRestoreGState(myContext);
}
- (void)drawRect:(CGRect)rect
{
// draw clock in clock view
[self drawClock:CGPointMake(rect.size.width/2,rect.size.height/2) hours:self.hours minutes:self.minutes seconds:self.seconds];
// test code for centering hands
// [self drawClock:CGPointMake(rect.size.width/2,rect.size.height/2) hours:12 minutes:00 seconds:00];
}