Динамически изменять 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. Этот рендерер только штрихует линию; это не заполняет это. Вы можете изменить цвет и другие атрибуты рисования многоугольника, изменив свойства, унаследованные от родительского класса. Вы обычно используете этот класс как есть и не делите его на подклассы.

Из библиотеки Apple

Класс MKPolylineView обеспечивает визуальное представление для объекта аннотации MKPolyline. Это представление штрихует путь, представленный аннотацией. (Этот класс не заполняет область, ограниченную путем.) Вы можете изменить цвет и другие атрибуты рисования пути, изменив свойства, унаследованные от класса MKOverlayPathView. Этот класс обычно используется как есть, а не подклассами.

Из библиотеки Apple

Другие вопросы по тегам