刷新 iPhone MapView 时出现问题

发布于 2024-11-05 06:19:11 字数 4145 浏览 8 评论 0原文

大家好,我在通过 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'

Hey guys, I am having trouble getting overlays in my map view to refresh via the setNeedsDisplayInMapRect: function. Here is the relevant code:

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;
    //...
}
//...

And I am not getting the "ParkingMapViewController.m mapView:viewForOverlay" output to console I am expecting. I have walked through he debugger and have ensured that the for loop is being reached and executed, however mapView:viewForOverlay: isn't being called for some reason. Anyone know what I am doing wrong? Thanks in advance!

EDIT 1:

I believe I have set the delegate, coordinates, and bounding rect properly, but please take a look...

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;
}
//...

Thanks.

EDIT 2:

An alternate method I have tried, to no avail:

ParkingMapViewController.m

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

Removing and re-adding all overlays ain't working too well for me. It merely crashes when that third line is executed. Any ideas?

EDIT 3:

So I changed the previously posted code to the following:

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

And am now seeing this in the console:

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

○闲身 2024-11-12 06:19:11

您可能没有正确设置 MKOverlay 上的坐标或 boundingMapRect 属性。 MapView 仅在认为视图可能可见时才会请求视图,如果其可见矩形不与 boundMapRect 相交,则不会。

另请确保您的 mapViewdelegate 设置正确。

Chances are you haven't set up the coordinate or boundingMapRect properties on the MKOverlay correctly. The MapView will only ask for the view if it thinks there is a possibility that it is visible, if its visible rect doesn't intersect the boundMapRect, it won't.

Also make sure your delegate for the mapView is set properly.

ゝ杯具 2024-11-12 06:19:11

所以我想通了。不一定是最有效的方法,但它对我有用。这就是我所做的:

[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

简而言之,我不必创建新函数,而只需调用我用来将叠加层加载到地图视图中的函数,效果很好!希望这可以帮助其他陷入类似情况的人。

编辑:

请务必注意,我正在重新加载注释和叠加层,如果没有先删除注释和叠加层,则如果重新加载函数被调用太多次,可能会导致应用程序崩溃。这就是我目前正在经历的。只是需要注意一些事情。为了解决这个问题,我将拥有单独的加载函数,一个用于覆盖,一个用于注释,这将被适当地调用。

So I figured it out. Not necessarily the most efficient method, but it works for me. This is what I did:

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

And here is 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

In short, I didn't have to create a new function but merely call the function I used to load overlays into the map view and that works fine! Hope this helps anyone else stuck in a similar situation.

EDIT:

Important to note that I am reloading BOTH annotations and overlays, and, if done without first removing both annotations and overlays, can lead to crashing of your app if the reload function is called too many times. This is what I am currently experiencing. Just something to be aware of. To fix this I am going to have separate load functions, one for overlays, and one for annotations which will be called appropriately.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文