MKPolyline не отображается на MKMapView

Вот код Это довольно просто. Я прокладываю путь для того, кто ходит. Итак, вот код для моего ViewController.m файл:

#import "ViewController.h"

@interface ViewController ()

@property BOOL firstTime;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self.mapView setDelegate:self];
    [self.mapView setShowsUserLocation:YES];
    [self.mapView setMapType:MKMapTypeHybrid];

    [self setLocationManager:[[CLLocationManager alloc] init]];
    [self.locationManager setDelegate:self];
    [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    [self.locationManager startUpdatingLocation];

    self.index = 0;

    self.firstTime = YES;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    if(self.firstTime)
    {
        CLLocation *startingLocation = [locations objectAtIndex:0];
        self.startingPointCooridinates = startingLocation.coordinate;
        self.index++;

        MKPointAnnotation *startingPointAnnotation = [[MKPointAnnotation alloc] init];
        startingPointAnnotation.title = @"Starting Point";
        startingPointAnnotation.coordinate = startingLocation.coordinate;

        [self.mapView addAnnotation:startingPointAnnotation];

        self.firstTime = false;
    }

    [self.locations addObject:[locations objectAtIndex:0]];

    CLLocationCoordinate2D coordinates[[self.locations count]];
    for(int i = 0; i < self.locations.count; i++)
    {
        CLLocation *currentLocation = [locations objectAtIndex:i];
        coordinates[i] = currentLocation.coordinate;
    }

    MKPolyline *pathPolyline = [MKPolyline polylineWithCoordinates:coordinates count:self.locations.count];
    [self.mapView addOverlay:pathPolyline];
}

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
    if([overlay isKindOfClass:[MKPolyline class]])
    {
        MKPolylineRenderer *polylineRenderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
        polylineRenderer.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
        polylineRenderer.strokeColor = [[UIColor redColor] colorWithAlphaComponent:0.7];
        polylineRenderer.lineWidth = 2.0;
        return polylineRenderer;
    }
    else
    {
        return  nil;
    }
}

Теперь отображается только аннотация, а MKPolyline появление. Что я делаю неправильно? Благодарю.

1 ответ

Решение
  1. Как уже упоминалось в комментариях, ваш locations массив никогда не выделяется и не инициализируется, так что это nil и призывает к нему (как addObject) ничего не делать и поэтому полилинии никогда не добавляются никакие координаты (и поэтому она не отображается).

    В viewDidLoadперед началом CLLocationManager, выделить и инициализировать массив:

    self.locations = [NSMutableArray array];
    
  2. Другая проблема, с которой вы столкнетесь, связана с didUpdateLocations в for цикл:

    CLLocation *currentLocation = [locations objectAtIndex:i];
    

    Вот, locations (без self.) относится к локальной переменной параметра метода делегата, а не к вашей locations переменная свойства уровня экземпляра класса. Компилятор должен предупредить вас об этом с помощью сообщения типа "Локальное объявление" location "скрывает переменную экземпляра".

    В этом случае предупреждение является критическим. То, что вы действительно хотите сделать здесь, это ссылка на locations Переменная свойства, в которой хранится полный список координат пользователя, а не локальная переменная, которая имеет только последние x не сообщенных местоположений (обычно только 1 объект).

    Так что эта строка должна быть изменена на:

    CLLocation *currentLocation = [self.locations objectAtIndex:i];
    

    Было бы лучше, если бы вы просто использовали другое имя, чем locations чтобы избежать этих проблем.

  3. Как также упоминалось в комментариях, поскольку вы добавляете наложение с полным следом движения пользователя каждый раз, когда пользователь перемещается, вам необходимо сначала удалить предыдущее наложение. В противном случае вам не нужно будет добавлять несколько наложений на карту, поскольку последнее наложение охватывает все движение. Предыдущие наложения явно не видны, поскольку имеют одинаковые координаты, одинаковый цвет и одинаковую ширину линии. Так что перед звонком addOverlayсамое простое - позвонить removeOverlays с текущим списком наложений карты:

    //remove any previous overlays first...
    [self.mapView removeOverlays:mapView.overlays];
    
    //now add overlay with the updated trail...
    [self.mapView addOverlay:pathPolyline];
    
  4. Незначительный момент, не влияющий на отображение, заключается в том, что настройка fillColor на полилинию не влияет. Вам нужно только установить strokeColor который делает код. Вы можете удалить вызов, чтобы установить fillColor,

  5. Наконец, вас может заинтересовать пример приложения Apple Breadcrumb. Их версия использует пользовательский оверлей, который можно динамически обновлять, не удаляя и не добавляя оверлеи каждый раз, когда происходит изменение или добавление.

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