Проблема обновления iPhone MapView - PullRequest
0 голосов
/ 05 мая 2011

Эй, ребята, у меня проблемы с наложением оверлеев на карту для обновления с помощью функции setNeedsDisplayInMapRect:. Вот соответствующий код:

ParkingMapViewController.m:

for (ParkingRegionOverlay *overlay in mapView.overlays) {
    [overlay setNeedsDisplayInMapRect:self.mapView.visibleMapRect];
}

//...
- (MKOverlayView *)mapView:(MKMapView *)mapView 
            viewForOverlay:(id <MKOverlay>)overlay
{   
    NSLog(@"ParkingMapViewController.m mapView:viewForOverlay");
    //...
}
//...

ParkingRegionOverlay.h:

@interface ParkingRegionOverlay : MKOverlayView <MKOverlay> {
    MKPolygon *polygon;
    MKMapRect boundingRect;
    CLLocationCoordinate2D centerCoord;
    //...
}
//...

И я не получаю вывод "ParkingMapViewController.m mapView: viewForOverlay" на консоль, которую я ожидаю. Я прошел через отладчик и убедился, что цикл for достигнут и выполнен, однако по какой-то причине mapView:viewForOverlay: не вызывается. Кто-нибудь знает, что я делаю не так? Заранее спасибо!

РЕДАКТ. 1:

Полагаю, я правильно установил делегат, координаты и ограничивающий прямоугольник, но, пожалуйста, посмотрите ...

ParkingMapViewController.h

@interface ParkingMapViewController : UIViewController <MKMapViewDelegate> {
    MKMapView *mapView;
//...

ParkingMapViewController.m:

//...
- (void)viewDidLoad {
    [super viewDidLoad];
    mapView.delegate = self;
//...

ParkingRegionOverlay.m:

//...
//initializes polygon and calculates bounding rect as well as its center coordinate
-(id)initWithPoints:(NSArray *)pointsArray andTitle:(NSString *)overlayTitle{
    MKMapPoint points[[pointsArray count]];
    double maxX = MIN_COORD_VAL;
    double minX = MAX_COORD_VAL;
    double maxY = MIN_COORD_VAL;
    double minY = MAX_COORD_VAL;
    double tempX = 0;
    double tempY = 0;

    if (self = [super init]) {
        int i = 0;
        //determine min/max extrema to help calculate the bounding rect
        for (id coordDict in pointsArray){
            tempX = [[coordDict objectForKey:@"latitude"] doubleValue];
            tempY = [[coordDict objectForKey:@"longitude"] doubleValue];
            maxX = fmax(tempX, maxX);
            minX = fmin(tempX, minX);
            maxY = fmax(tempY, maxY);
            minY = fmin(tempY, minY);

            CLLocationCoordinate2D coord = {tempX,tempY};
            points[i] = MKMapPointForCoordinate(coord);
            i++;
        }//for

        CLLocationCoordinate2D northWestCorner = CLLocationCoordinate2DMake(maxX, minY);
        CLLocationCoordinate2D southEastCorner = CLLocationCoordinate2DMake(minX, maxY);
        MKMapPoint northWestPoint = MKMapPointForCoordinate(northWestCorner);
        MKMapPoint southEastPoint = MKMapPointForCoordinate(southEastCorner);
        boundingRect = MKMapRectMake(northWestPoint.x, northWestPoint.y, 
                                     (southEastPoint.x-northWestPoint.x), 
                                     (southEastPoint.y-northWestPoint.y));

        centerCoord = CLLocationCoordinate2DMake((maxX-minX)/2,(maxY-minY)/2);
        polygon = [MKPolygon polygonWithPoints:points count:[pointsArray count]];
        polygon.title = overlayTitle;

        [self initAcceptedPermitsBasedOnTitle:overlayTitle];
    }//if

    return self;
}
//...

Спасибо.

РЕДАКТИРОВАТЬ 2:

Альтернативный метод, который я пробовал, но безрезультатно:

ParkingMapViewController.m

    NSArray *overlayArray = [[NSArray alloc] initWithArray:[mapView overlays]];
    [self.mapView removeOverlays:mapView.overlays];
    [self.mapView addOverlays:overlayArray];

Удаление и повторное добавление всех оверлеев не слишком хорошо для меня. Он просто падает, когда эта третья строка выполняется. Есть идеи?

РЕДАКТИРОВАТЬ 3:

Поэтому я изменил ранее опубликованный код на следующий:

NSArray *overlayArray = [mapView overlays];
[self.mapView removeOverlays:overlayArray];
[self.mapView addOverlays:overlayArray];

И теперь я вижу это в консоли:

2011-05-05 14:24:54.145 Parking[68501:207] -[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0
2011-05-05 14:24:54.147 Parking[68501:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber boundingMapRect]: unrecognized selector sent to instance 0xa9afae0'

Ответы [ 2 ]

0 голосов
/ 06 мая 2011

Так что я понял это. Не обязательно самый эффективный метод, но он работает для меня. Вот что я сделал:

[self.mapView removeOverlays:[mapView overlays]];
[self loadOverlaysAndAnnotations];

А вот и loadOverlaysAndAnnotations:

- (void)loadOverlaysAndAnnotations {

    NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    CoreDataSingleton *coreDataSingleton = [CoreDataSingleton sharedManager];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"ParkingLot" inManagedObjectContext:[coreDataSingleton managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [[coreDataSingleton managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *overlayEntity in fetchedObjects) {
        NSArray *pointsArray = [NSArray arrayWithArray:[overlayEntity valueForKey:@"overlayCoordPoints"]];
        ParkingRegionOverlay *regionPolygon = [[ParkingRegionOverlay alloc] initWithPoints:pointsArray andTitle:[overlayEntity valueForKey:@"lotName"]];
        [mapView addOverlay:regionPolygon];
        [regionPolygon release];


        NSSet *annotationsSet = [NSSet setWithSet:[overlayEntity valueForKey:@"parkingAnnotations"]];
        NSArray *allAnnotations = [NSArray arrayWithArray:[annotationsSet allObjects]];
        CLLocationCoordinate2D workingCoordinate;
        for (ParkingAnnotations *annotation in allAnnotations) {
            ParkingAnnotation *parkingAnnot = [[ParkingAnnotation alloc] init];
            workingCoordinate.latitude = [[annotation latitude] doubleValue];
            workingCoordinate.longitude = [[annotation longitude] doubleValue];
            [parkingAnnot setCoordinate:workingCoordinate];
            [parkingAnnot setTitle:[overlayEntity valueForKey:@"lotName"]];
            if ([[overlayEntity valueForKey:@"lotName"] isEqualToString:@"VP 1"]) {
                [parkingAnnot setLot:lot1];
            }

            [mapView addAnnotation:parkingAnnot];
            [parkingAnnot release];
        }
    }        
    [fetchRequest release];
}//loadOverlaysAndAnnotations

Короче говоря, мне не нужно было создавать новую функцию, а просто вызывать функцию, которую я использовал для загрузки наложений в представление карты, и это прекрасно работает! Надеюсь, это поможет кому-нибудь еще застрявшему в подобной ситуации.

EDIT:

Важно отметить, что я перезагружаю ОБА аннотации и наложения, и, если это делается без предварительного удаления как аннотаций, так и наложений, может привести к сбою приложения, если функция перезагрузки вызывается слишком много раз. Это то, что я сейчас испытываю. Просто что-то, о чем нужно знать. Чтобы это исправить, у меня будут отдельные функции загрузки, одна для наложений и одна для аннотаций, которые будут вызываться соответствующим образом.

0 голосов
/ 05 мая 2011

Скорее всего, вы не настроили координату или свойства boundingMapRect на MKOverlay правильно. MapView будет запрашивать представление только в том случае, если думает, что есть вероятность, что оно является видимым, если его видимый прямоугольник не пересекает boundMapRect, он не будет.

Также убедитесь, что ваш delegate для mapView установлен правильно.

...