简体   繁体   English

从未调用mapView viewForOverlay

[英]mapView viewForOverlay never called

So I want to display where my app's user walked on a MKMapView , I collect datas with the following code : 所以我想显示我的应用程序用户在MKMapView上走的位置,我使用以下代码收集数据:

#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {

    // calc. distance walked
    CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];
    self.totalMetters += meters;
    [[self labelDistance] setText:[self formatDistanceIntoString:self.totalMetters]];

   //  create another annotation
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    annotation.coordinate = newLocation.coordinate;

    // Also add to our map so we can remove old values later
    [self.locations addObject:annotation];

    // Remove values if the array is too big
    while (self.locations.count > 100)
    {
        annotation = [self.locations objectAtIndex:0];
        [self.locations removeObjectAtIndex:0];

        // Also remove from the map
        [self.map removeAnnotation:annotation];
    }

Once it's finished, I call my draw method : 一旦完成,我称之为draw方法:

[self drawRoute];

Which contains the following : 其中包含以下内容:

- (void)drawRoute {

    NSLog(@"drawRoute");
    NSInteger pointsCount = self.locations.count;

    CLLocationCoordinate2D pointsToUse[pointsCount];

    for(int i = 0; i < pointsCount; i++) {
        MKPointAnnotation *an = [self.locations objectAtIndex:i];
        pointsToUse[i] = CLLocationCoordinate2DMake(an.coordinate.latitude,an.coordinate.latitude);
    }

    MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:pointsToUse count:pointsCount];

    [self.map addOverlay:myPolyline];
}

Finally my mapView delegate : 最后我的mapView委托:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {
    NSLog(@"route");
    if ([overlay isKindOfClass:MKPolyline.class]) {
        MKPolylineView *lineView = [[MKPolylineView alloc] initWithOverlay:overlay];
        lineView.strokeColor = [UIColor greenColor];

        return lineView;
    }
    return nil;
}

Obviously my controller is MKMapView Delegate conform 显然我的控制器是MKMapView Delegate符合

@interface NewWalkViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate> 

And the mapView in the Storyboard is linked to the controller (outlet and delegate) StoryboardmapView链接到控制器(插座和代理)

I use the "bike road" debug tool and there is the output : 我使用“自行车道”调试工具,有输出:

2014-01-25 20:27:30.132 The walking dog[2963:70b] new location : 37.330435 2014-01-25 20:27:30.132遛狗[2963:70b]新址:37.330435

2014-01-25 20:27:30.133 The walking dog[2963:70b] drawRoute 2014-01-25 20:27:30.133遛狗[2963:70b] drawRoute

As I can see the method for drawing the overlay is never called, and I don't have a single clue how to fix it. 正如我所看到的,绘制叠加层的方法永远不会被调用,而且我没有一个线索如何解决它。

The main problem is that in drawRoute , this line is passing latitude for both parameters to CLLocationCoordinate2DMake : 主要问题是在drawRoute ,这一行将两个参数的latitude传递给CLLocationCoordinate2DMake

pointsToUse[i] = CLLocationCoordinate2DMake
                     (an.coordinate.latitude,an.coordinate.latitude);

This results in the line being drawn in a different part of the world than where the actual an.coordinate is. 这导致在世界的不同部分绘制线条而不是实际的an.coordinate For example, if an.coordinate is 37,-122 (somewhere near San Francisco), the line is being drawn instead at 37,37 (somewhere in southern Turkey). 例如,如果an.coordinate是37,-122(旧金山附近的某个地方),则该线被绘制为37,37(土耳其南部某处)。

Since you are not actually positioning the map at the wrong location (you are looking for the line at the "right" location), viewForOverlay is never called because the map only calls it when it's possible that the overlay will be visible. 由于您实际上并未将地图定位在错误的位置(您正在寻找“右侧”位置的线), viewForOverlay从不调用viewForOverlay因为地图仅在覆盖可能可见时才调用它。


Change that line to: 将该行更改为:

pointsToUse[i] = CLLocationCoordinate2DMake
                     (an.coordinate.latitude,an.coordinate.longitude);

or simply: 或者干脆:

pointsToUse[i] = an.coordinate;


As James Frost mentions in the comments, as of iOS 7, you should be using rendererForOverlay instead of viewForOverlay though the map view will still call viewForOverlay in iOS 7 if rendererForOverlay has not been implemented. 正如James Frost在评论中提到的,从iOS 7开始,你应该使用rendererForOverlay而不是viewForOverlay尽管如果还没有实现rendererForOverlay ,地图视图仍将在iOS 7中调用viewForOverlay Though this isn't preventing your overlay from displaying in the current case, you should implement the new delegate method as well as the old one (if the iOS 7 app will also be running on iOS 6 or earlier). 虽然这不会阻止您的叠加显示在当前情况下,但您应该实现新的委托方法以及旧委托方法(如果iOS 7应用程序也将在iOS 6或更早版本上运行)。


Another important but unrelated issue is that you are unnecessarily creating multiple, overlapping overlays. 另一个重要但不相关的问题是您不必要地创建多个重叠的叠加层。 In drawRoute , since the overlay you are creating includes all the locations, you should remove any existing overlays before adding the new one. drawRoute ,由于您要创建的叠加层包含所有位置,因此在添加新叠加层之前应删除所有叠加层。 Otherwise, the map ends up with an overlay for location 0 to 1, an overlay for location 0 to location 2, an overlay for location 0 to location 3, etc. The previous overlays are not obviously visible since they have the same color and line width. 否则,地图最终会显示位置0到1的叠加层,位置0到位置2的叠加层,位置0到位置3的叠加层等。之前的叠加层显然不可见,因为它们具有相同的颜色和线条宽度。 Before the addOverlay line, put: addOverlay行之前,放入:

[self.map removeOverlays:self.map.overlays];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM