相对于缩放级别缩放MKMapView Annotations

时间:2010-05-22 13:44:39

标签: objective-c cocoa-touch uiview mkmapview mkannotationview

问题 我正在尝试围绕一个圆周方向创建一个视觉半径圆,它实际上保持固定的大小。例如。因此,如果我将半径设置为100米,当您缩小地图视图时,半径圆会逐渐变小。

我已经能够实现缩放,但是当用户操纵视图时,半径rect / circle似乎远离Pin地标“抖动”。

我认为在即将推出的iPhone OS 4上更容易实现,但我的应用程序需要支持3.0。

表现形式 这是行为的video

实施 注释以通常的方式添加到Mapview中,我在我的UIViewController子类( MapViewController )上使用了委托方法来查看区域何时发生变化。

-(void)mapView:(MKMapView *)pMapView regionDidChangeAnimated:(BOOL)animated{

//Get the map view
MKCoordinateRegion region;
CGRect rect;

//Scale the annotations
for( id<MKAnnotation> annotation in [[self mapView] annotations] ){

    if( [annotation isKindOfClass: [Location class]] && [annotation conformsToProtocol:@protocol(MKAnnotation)] ){
        //Approximately 200 m radius
        region.span.latitudeDelta = 0.002f;
        region.span.longitudeDelta = 0.002f;

        region.center = [annotation coordinate];

        rect = [[self mapView] convertRegion:region toRectToView: self.mapView];

        if( [[[self mapView] viewForAnnotation: annotation] respondsToSelector:@selector(setRadiusFrame:)] ){

            [[[self mapView] viewForAnnotation: annotation] setRadiusFrame:rect];

        }

    }

}

Annotation对象( LocationAnnotationView )是MKAnnotationView的子类,它的setRadiusFrame看起来像这样

-(void) setRadiusFrame:(CGRect) rect{

CGPoint centerPoint;

//Invert
centerPoint.x = (rect.size.width/2) * -1;
centerPoint.y = 0 + 55 + ((rect.size.height/2) * -1);

rect.origin = centerPoint;

[self.radiusView setFrame:rect];
}

最后,radiusView对象是UIView的子类,它会覆盖drawRect方法以绘制半透明圆。 setFrame也在这个UIView子类中被覆盖,但除了[UIView setFrame:]之外,它只用于调用[UIView setNeedsDisplay]以确保在更新帧之后重新绘制视图。

radiusView对象的( CircleView )drawRect方法看起来像这样

-(void) drawRect:(CGRect)rect{

//NSLog(@"[CircleView drawRect]");

[self setBackgroundColor:[UIColor clearColor]];
//Declarations
CGContextRef context;
CGMutablePathRef path;

//Assignments
context = UIGraphicsGetCurrentContext();

path = CGPathCreateMutable();

//Alter the rect so the circle isn't cliped

//Calculate the biggest size circle
if( rect.size.height > rect.size.width ){
    rect.size.height = rect.size.width;
}
else if( rect.size.height < rect.size.width ){
    rect.size.width = rect.size.height;
}

rect.size.height -= 4;
rect.size.width  -= 4;
rect.origin.x += 2;
rect.origin.y += 2;

//Create paths
CGPathAddEllipseInRect(path, NULL, rect );

//Create colors
[[self areaColor] setFill];

CGContextAddPath( context, path);
CGContextFillPath( context );

[[self borderColor] setStroke];

CGContextSetLineWidth( context, 2.0f );
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextAddPath(context, path );
CGContextStrokePath( context );
CGPathRelease( path );

//CGContextRestoreGState( context );

}

感谢您的支持,感谢任何帮助。 乔纳森

1 个答案:

答案 0 :(得分:5)

首先,第一个函数中使用的foo是什么?我假设radiusView的父级是注释视图,对吗?

“抖动”

此外,radiusView的中心点应与annotationView的中心点重合。这应该可以解决您的问题:

-(void) setRadiusFrame:(CGRect)rect{
    rect.origin.x -= 0.5*(self.frame.size.width - rect.size.width);
    rect.origin.y -= 0.5*(self.frame.size.height - rect.size.height);
    [self.radiusView setFrame:rect]
}

不必要的方法

您可以直接在radiusView上设置框架并避免上述计算:

    UIView * radiusView = [[[self mapView] viewForAnnotation: annotation] radiusView];
    rect = [[self mapView] convertRegion:foo toRectToView: radiusView.superView];
    [radiusView setFrame:rect];
  1. 绘制椭圆时,请勿使用传递给rect的{​​{1}},它不必与框架相同。直接使用drawRect:
  2. 更安全

    不必要的观点

    如果您需要使用上述层次结构,我现在给出了以上几点,但我不明白为什么不直接在self.frame中绘制省略号?毕竟,它就是出于这个目的。这是你这样做的:

    1. 缩放时,直接更改annotationView的rect:

      LocationAnnotationView
    2. rect = [[self mapView] convertRegion:foo toRectToView: self.mapView]; [[[self mapView] viewForAnnotation: annotation] setFrame:rect]; 的实施方式移至drawRect:

    3. 这更容易实现,并且应该解决您的问题,因为注释视图的中心点随您的引脚移动而您不应该看到此问题。

      修复

      代码中还有两个问题:

      1. 像这样设置longitudeDelta:

        LocationAnnotationView

        随着转换为米的经度增量随纬度的变化而变化。或者,您只能设置纬度增量,然后修改矩形,使其变为矩形(region.span.longitudeDelta = 0.002*cos(region.center.latitude*pi/180.0); )。

      2. width==height
      3. ,请勿使用传递的drawRect:;而是使用rect。不能保证这些是相同的,self.frame可以有任何价值。

      4. 让我知道这些是否有效; - )