用石英绘制航向角视图

发布于 2024-11-18 12:01:39 字数 205 浏览 1 评论 0原文

我只是想像地图应用程序一样在 MKMapView 上绘制标题角度视图,当然我可以使用 Photoshop 或任何必要的程序来做到这一点。但我不需要考虑视网膜显示或屏幕差异。是否可以用石英或任何相关的内置库绘制这个形状以及如何绘制?

在此处输入图像描述

提前致谢。

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 shape with quartz or any related built in library and how ?

enter image description here

thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

行雁书 2024-11-25 12:01:39

你可以 ;)
为此,您需要实现此方法:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation

在此方法中,您必须仅针对注释的用户位置情况创建 MKAnnotationView 子类的实例,例如:

- (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;
}

注意 KVO 语句,让您的自定义 MKAnnotationView 值已更改
在你的 MKAnnotationView 子类中,你需要重写drawRect;例如,

- (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);
}

这绘制了一个带有紫色线的红色标线,显示标题(在我的示例中,课程被窃听,因为我在三角学方面很弱;)但它绘制了:)

您当然需要处理 KVO 通知,例如

-(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]);
}

-setNeedsDisplay 将触发重绘。

确保您的自定义视图具有非零矩形框架,并且不要为其设置图像。

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.

幻想少年梦 2024-11-25 12:01:39

以前没有使用过 MKMapView,但您也许可以对其进行子类化,并在您的 drawRect: 方法中首先绘制超类,然后使用标准 CG 绘制方法在其顶部绘制您的航向角度。

- (void)drawRect:(NSRect)dirtyRect
{
    [super drawRect:dirtyRect];

    // Your drawing goes here
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文