Jon*_*han 14 cocoa-touch objective-c uiview mkmapview mkannotationview
问题 我正试图在一个圆周方向上创建一个视觉半径圆,它实际上保持固定的大小.例如.因此,如果我将半径设置为100米,当您缩小地图视图时,半径圆会逐渐变小.
我已经能够实现缩放,但是当用户操纵视图时,半径rect/circle似乎远离Pin Placemark"抖动".
我相信这在即将推出的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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
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];
}
Run Code Online (Sandbox Code Playgroud)
最后,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 );
}
Run Code Online (Sandbox Code Playgroud)
感谢您对我的支持,任何帮助表示赞赏.乔纳森
首先,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]
}
Run Code Online (Sandbox Code Playgroud)
您可以直接在框架上设置框架radiusView并避免上述计算:
UIView * radiusView = [[[self mapView] viewForAnnotation: annotation] radiusView];
rect = [[self mapView] convertRegion:foo toRectToView: radiusView.superView];
[radiusView setFrame:rect];
Run Code Online (Sandbox Code Playgroud)
rect传递给drawRect:它,它不必与框架相同.直接使用更安全self.frame如果你需要使用上面的层次结构,我现在给出了上述几点,但我不明白你为什么不直接在你的省略号中绘制LocationAnnotationView?毕竟,它就是为了这个目的而存在的.这是你如何做到这一点:
缩放时,直接更改annotationView的rect:
rect = [[self mapView] convertRegion:foo toRectToView: self.mapView];
[[[self mapView] viewForAnnotation: annotation] setFrame:rect];
Run Code Online (Sandbox Code Playgroud)将执行移动drawRect:到LocationAnnotationView.
这更容易实现,并且应该解决您的问题,因为注释视图的中心点随您的引脚移动而您不应该看到此问题.
代码中还有两个问题:
像这样设置longitudeDelta:
region.span.longitudeDelta = 0.002*cos(region.center.latitude*pi/180.0);
Run Code Online (Sandbox Code Playgroud)
随着转换为米的经度增量随纬度的变化而变化.或者,您只能设置纬度增量,然后修改矩形,使其变为矩形(width==height).
在drawRect:,不要使用通过rect; 改为使用self.frame.不能保证这些是相同的,并且rect可以有任何价值.
如果这些工作让我知道;-)
| 归档时间: |
|
| 查看次数: |
6192 次 |
| 最近记录: |