Archive for March, 2010

28 MarAnalog Clock using Quartz Core

Just want to share a simple example of using Quartz. I took a classic graphic task for – Analog Clock.

The drawing code is short and simple. It’s just necessary to undesrtand how measure angles of clock arrows from NSDatae and feel the difference between degrees and radians ;)

Inherite UIView and redefine “- (void)drawRect:(CGRect)rect ” method, which run when a UIView need to be displayed.
Mesure angles in readians from [NSDatae date] for Hour, Minute and Second.
Draw lines of clock arrows. A start point is the clock’s center. The end point is depends on measured angle.

inline double rad(double deg)
{
return deg / 180.0 * M_PI;
}

- (void) drawLineForContext:(const CGContextRef&)context Width:(float)_width angle:(double)_angle length:(double)radius
{
CGPoint c = CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0);

CGContextSetLineWidth(context, _width);
CGContextMoveToPoint(context, self.center.x, self.center.y);
CGPoint addLines[] =
{
CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0),
CGPointMake(radius*cos(_angle) +c.x, radius*sin(_angle) +c.y),
};

CGContextAddLines(context, addLines, sizeof(addLines)/sizeof(addLines[0]));
CGContextStrokePath(context);
}

- (void)drawRect:(CGRect)rect
{
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate* now = [NSDate date];
int h = [[cal components:NSHourCalendarUnit fromDate:now] hour];
int m = [[cal components:NSMinuteCalendarUnit fromDate:now] minute];
int s = [[cal components:NSSecondCalendarUnit fromDate:now] second];
[cal release];

BOOL isAM = hdouble hAlpha = rad((isAM?h:h-12)*30 +(30*m/60) -90);
double mAlpha = rad(m*6 -90);
double sAlpha = rad(s*6 -90);

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
[self drawLineForContext:context Width:8.0 angle:hAlpha length:self.frame.size.width/2.0 - 18];
[self drawLineForContext:context Width:5.0 angle:mAlpha length:self.frame.size.width/2.0 - 12];
[self drawLineForContext:context Width:2.0 angle:sAlpha length:self.frame.size.width/2.0 - 10];
}
To finish the AnalogClock class it’s need start and stop methods:
-(void)update
{
[self setNeedsDisplay];
}

-(void)startClockUpdates
{
[self update];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(update) userInfo:nil repeats:YES];
}
-(void)stopClockUpdates
{
[timer invalidate], timer = nil;
}

To use the clocks you need to add our custom UIView to any UIViewController and call the start method.

#import “AnalogClockViewController.h”

@implementation AnalogClockViewController

- (void) viewWillAppear:(BOOL)animated
{
[clock startClockUpdates];
}

- (void) viewWillDisappear:(BOOL)animated
{
[clock stopClockUpdates];
}

- (void)dealloc {
[super dealloc];
}

@end

16 MarIcon.png, Default.png and Resources problem using several Target settings

There is can a problem with resources when you use several target for your project. So if you’ve added the Icon.png or Default.png or some other resource file and the app does not show it then select the resource and move it to Targets/aTarget/Copy Bundle Resources. Trust me, it helps.

BTW, you cannot I don’t know how to set different Default.png(s) for each target, so rename them when necessary.