Динамически изменять lineWidth mkpolyline
В моем приложении есть карта, которая перемещается в соответствии с местоположением пользователя. Я успешно нарисовал ломаную линию для источника и пункта назначения. Используя следующий код
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay{
MKPolylineView *view1 = [[MKPolylineView alloc] initWithOverlay:overlay];
view1.lineWidth = 27.0;
view1.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];
return view1;
}
Но моя проблема в том, что когда карта движется, то есть, когда я перемещаю пользователя, я изменяю регион карты, тогда иногда полилиния не отображается хорошо, а иногда ее толщина превышает фактический размер, как вы можете видеть на рисунке ниже.
Я прилагаю изображение ниже, пожалуйста, дайте мне знать, что я могу сделать для плавной полилинии, когда карта движется.
РЕДАКТИРОВАТЬ
Как предложил Мэтт, я создал подкласс MKPolylineRenderer и реализовал метод drawMapRect, как показано ниже:
-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
CGMutablePathRef fullPath = CGPathCreateMutable();
BOOL pathIsEmpty = YES;
//merging all the points as entire path
for (int i=0;i< self.polyline.pointCount;i++){
CGPoint point = [self pointForMapPoint:self.polyline.points[i]];
if (pathIsEmpty){
CGPathMoveToPoint(fullPath, nil, point.x, point.y);
pathIsEmpty = NO;
} else {
CGPathAddLineToPoint(fullPath, nil, point.x, point.y);
}
}
//get bounding box out of entire path.
CGRect pointsRect = CGPathGetBoundingBox(fullPath);
CGRect mapRectCG = [self rectForMapRect:mapRect];
//stop any drawing logic, cuz there is no path in current rect.
if (!CGRectIntersectsRect(pointsRect, mapRectCG))return;
UIColor *darker = [UIColor blackColor];
CGFloat baseWidth = 10 / zoomScale;
// draw the dark colour thicker
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, darker.CGColor);
CGContextSetLineWidth(context, baseWidth * 1.5);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
// now draw the stroke color with the regular width
CGContextAddPath(context, self.path);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, baseWidth);
CGContextSetLineCap(context, self.lineCap);
CGContextStrokePath(context);
[super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}
Но та же проблема См. Изображение ниже:
Хорошо, я думаю, что у меня есть проблема, моя полилиния добавляется один раз, но, как скорость пользователя, я изменяю уровень масштабирования MKMapView, уровень масштабирования изменяется, но ширина полилинии не обновляется,
Так как я могу динамически изменить lineWidth mkpolyline??
3 ответа
Проблема в том, что вы настраиваете lineWidth
на фиксированной ширине (действительно большая фиксированная ширина). Это становится больше или меньше, когда карта увеличивается или уменьшается.
Вместо этого реализуйте свой собственный подкласс MKOverlayRenderer и переопределите drawMapRect:zoomScale:inContext:
, Получает zoomScale
параметр, и поэтому вы можете отрегулировать ширину вашей линии, чтобы хорошо выглядеть на текущем масштабе.
Подкласс MKPolylineRenderer и переопределение applyStrokePropertiesToContext:atZoomScale:
так что он игнорирует масштаб и рисует линии с постоянной шириной:
@interface ConstantWidthPolylineRenderer : MKPolylineRenderer
@end
@implementation ConstantWidthPolylineRenderer
- (void)applyStrokePropertiesToContext:(CGContextRef)context
atZoomScale:(MKZoomScale)zoomScale
{
[super applyStrokePropertiesToContext:context atZoomScale:zoomScale];
CGContextSetLineWidth(context, self.lineWidth);
}
@end
Теперь используйте его и восхищайтесь его плавным рендерингом:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
MKPolyline *polyline = (MKPolyline *)overlay;
ConstantWidthPolylineRenderer *renderer = [[ConstantWidthPolylineRenderer alloc] initWithPolyline:polyline];
renderer.strokeColor = [UIColor redColor];
renderer.lineWidth = 40;
return renderer;
}
Вам нужно использовать MKPolylineRenderer
вместо MKPolylineView
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id < MKOverlay >)overlay {
@try {
MKPolylineRenderer *renderer = [[[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.lineWidth = 27.0;
renderer.strokeColor = [UIColor colorWithRed:55.0/255.0 green:168.0/255.0 blue:219.0/255.0 alpha:1];
return renderer;
}
@catch (NSException *exception) {
NSLog(@"exception :%@",exception.debugDescription);
}
}
Прочитайте это:
Класс MKPolylineRenderer предоставляет визуальное представление для объекта наложения MKPolyline. Этот рендерер только штрихует линию; это не заполняет это. Вы можете изменить цвет и другие атрибуты рисования многоугольника, изменив свойства, унаследованные от родительского класса. Вы обычно используете этот класс как есть и не делите его на подклассы.
Класс MKPolylineView обеспечивает визуальное представление для объекта аннотации MKPolyline. Это представление штрихует путь, представленный аннотацией. (Этот класс не заполняет область, ограниченную путем.) Вы можете изменить цвет и другие атрибуты рисования пути, изменив свойства, унаследованные от класса MKOverlayPathView. Этот класс обычно используется как есть, а не подклассами.