Проблема я пытаюсь создать визуальный круг радиуса вокруг annonation, который остается в фиксированном размере в реальном выражении. Например, Поэтому Если я установил радиус на 100 м, поскольку Вы масштабируете из представления Map, круг радиуса прогрессивно становится меньшим.
Я смог достигнуть масштабирования, однако радиус rect/circle, кажется, "Дрожит" далеко от Контакта 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 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];
}
}
}
Объект аннотации (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 setNeedsDisplay] в дополнение к [UIView setFrame:], чтобы гарантировать, что представление перерисовывается после того, как кадр был обновлен.
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 );
}
Спасибо за терпение меня ценится любая справка. Jonathan
Во-первых, что 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];
] rect
передается в drawRect:
, он не обязательно должен совпадать с фреймом. Безопаснее напрямую использовать self.frame
Теперь я привел вышеупомянутые моменты, если вам нужно использовать указанную выше иерархию, но я не понимаю, почему бы вам просто не нарисовать свои эллипсы напрямую в LocationAnnotationView
? В конце концов, он существует для этой цели. Вот как вы это делаете:
при масштабировании напрямую измените прямоугольник annotationView:
rect = [[self mapView] convertRegion: foo toRectToView: self.mapView];
[[[self mapView] viewForAnnotation: аннотация] setFrame: rect];
Переместите реализацию drawRect:
в LocationAnnotationView
.
Это проще реализовать, и это должно решить вашу проблему, поскольку центральная точка аннотации перемещается вместе с вашим булавкой, и вы не должны видеть эту проблему.
В коде есть еще две проблемы:
Установите longitudeDelta следующим образом:
region.span.longitudeDelta = 0.002 * cos (регион.центр. Широта * пи / 180,0);
, поскольку дельта долготы, преобразованная в метры, изменяется с широтой. В качестве альтернативы вы можете установить только дельту широты, а затем изменить прямоугольник, чтобы он стал прямоугольным ( ширина == высота
).
в drawRect:
, не используйте переданный rect
; вместо этого используйте self.frame
. Нет никакой гарантии, что они одинаковы, и rect
может иметь любое значение.
Сообщите мне, работают ли они; -)