【问题标题】:Problem Refreshing iPhone MapView刷新 iPhone MapView 的问题
【发布时间】:2011-05-05 12:09:07
【问题描述】:

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

【问题讨论】:

  • viewForOverlay 最初是否被调用?叠加层是否显示?您在需要刷新的叠加层中进行了哪些更改?有趣的是,ParkingRegionOverlay 既是 MKOverlayView 的子类,又实现了 MKOverlay 协议。不确定这是否与它有关。
  • 是的,viewForOverlay 最初会被调用,并且所有的叠加层都会正确显示。如果边界矩形没有正确设置,叠加层不会出现吗?这就是为什么我怀疑这是否是问题所在。在用户输入一些信息后,我正在尝试更改叠加层的颜色(并非所有叠加层都会改变)。是的,我曾经让 ParkingRegionOverlay 成为 NSObject 的子类,但是 setNeedsDisplayInMapRect: 不起作用,所以我将它设为子类,现在它没有抱怨,但是什么也没发生。我不确定这样做是否是标准的。请参见上文。

标签: iphone cocoa-touch refresh mkmapview mkoverlay


【解决方案1】:

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

还要确保您的delegatemapView 设置正确。

【讨论】:

  • 感谢您的回复,请看我上面编辑的帖子。
【解决方案2】:

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

[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

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

编辑:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 2011-08-04
    相关资源
    最近更新 更多