drawing heading angle view with quartz
I just wanted to draw heading angle view on MKMapView like Maps app, Of course I can do that with photoshop or any necessary program. But I don't need to consider retina display or screen differences. Is it possible to draw this sha开发者_如何学JAVApe with quartz or any related built in library and how ?
thanks in advance.
You can ;) To do so, you need to implement this method :
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
In this one you will have to create a instance of a subclass of MKAnnotationView only for the user location case of annotation like:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
if (userView == nil) {
userView=[[[UserLocationView alloc]
initWithAnnotation:annotation reuseIdentifier:@"user"]
autorelease];
}
[self addObserver:userView forKeyPath:@"userHeading" options:NSKeyValueObservingOptionNew context:NULL] ;
return userView ;
}
return nil;
}
Note the KVO statement to let your custom MKAnnotationView that the value has changed in your MKAnnotationView subclass you need to override drawRect; like that for example
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
NSAssert(context !=nil, @"Context was nil") ;
CGContextSetRGBStrokeColor (context,1.0f,0.0f,0.0f,1.0f) ;
CGContextSetLineWidth(context, 2.0f);
CGContextMoveToPoint(context, 0, 15);
CGContextAddLineToPoint(context, 30, 15);
CGContextMoveToPoint(context, 15,0);
CGContextAddLineToPoint(context, 15, 30);
CGContextStrokePath(context);
CGContextSetLineWidth(context, 4.0f);
CGContextAddArc (context,15,15,13,0,6.28,0);
CGContextStrokePath(context);
hdg = radians([self heading]);
dx = self.frame.size.width / 2 ;
dy = self.frame.size.height/ 2 ;
if (hdg < M_PI) {
y = (cos(hdg) * dy ) - dy ;
x = (sin(hdg) * dx ) + dx ;
} else {
y = (cos(hdg) * dy ) + dy ;
x = (sin(hdg) * dx ) + dx ;
}
// NSLog(@"Heading:%3f Hdg:%3f X:%3f Y:%3f", heading, hdg, x, y) ;
CGContextSetRGBStrokeColor (context,1.0f,0.0f,1.0f,1.0f) ;
CGContextSetLineWidth(context, 2.0f);
CGContextMoveToPoint(context, dx,dy);
CGContextAddLineToPoint(context, x, y);
CGContextStrokePath(context);
}
This draws a red reticle with a purple line showing the heading (in my sample the course is bugged because i am just weak in trigonometry ;) but it draws :)
You of course need to handle the KVO notification like:
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[self setHeading: [[change objectForKey:NSKeyValueChangeNewKey]doubleValue]] ;
[self setNeedsDisplay] ;
NSLog(@"Heading is %f", [self heading]);
}
the -setNeedsDisplay
will trigger the redraw.
Make sure that you custom view has a non-zero rect frame, and do NOT set an image to it.
Having not used MKMapView before, but you might be able to subclass it and in your drawRect: method first draw the superclass and then use standard CG drawing methods to draw your heading angle on top of it.
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
// Your drawing goes here
}
精彩评论