問題 注釈の周りにビジュアル半径の円を作成しようとしていますが、これは実際には固定サイズのままです。例えば。したがって、半径を 100m に設定すると、マップ ビューをズームアウトすると、半径の円が徐々に小さくなります。
スケーリングを達成できましたが、ユーザーがビューを操作すると、半径の四角形/円がピンの目印から「ジッター」しているように見えます。
これは、次期 iPhone OS 4 で実現するのがはるかに簡単になると思われますが、私のアプリケーションは 3.0 をサポートする必要があります。
症状 ここに行動のビデオがあります。
実装 注釈は通常の方法で 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 );
}
ご協力いただきありがとうございます。ジョナサン