【问题标题】:mapView viewForOverlay never calledmapView viewForOverlay 从未调用过
【发布时间】:2014-01-25 19:35:43
【问题描述】:

所以我想显示我的应用用户在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];
    }

一旦完成,我调用我的 draw 方法:

[self drawRoute];

其中包含以下内容:

- (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];
}

最后是我的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;
}

显然我的控制器是MKMapView Delegate 一致

@interface NewWalkViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate> 

并且Storyboard 中的mapView 链接到控制器(出口和委托)

我使用“自行车道”调试工具,有输出:

2014-01-25 20:27:30.132 遛狗[2963:70b] 新位置:37.330435

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

正如我所见,绘制叠加层的方法从未被调用过,而且我不知道如何修复它。

【问题讨论】:

  • 您是否尝试过实现- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id &lt; MKOverlay &gt;)overlay;?在 iOS 7 中,mapView:viewForOverlay:deprecated。不过,恐怕我没有在 iOS 7 上完成足够的 MapKit 编程来帮助您实现。
  • 在 drawRoute 中,当设置 pointsToUse[i] 时,您将两个参数的纬度传递给 CLLocationCoordinate2DMake。另外,你可以直接说pointsToUse[i] = an.coordinate;
  • @JamesFrost :谢谢,我会和这个代表核实一下
  • @Anna 没看到,改了,谢谢

标签: ios objective-c ios7 mkmapview mkoverlay


【解决方案1】:

主要问题是在drawRoute 中,这一行将latitude 的两个参数都传递给CLLocationCoordinate2DMake

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

这会导致在世界上与实际an.coordinate 所在位置不同的地方绘制线。例如,如果 an.coordinate 是 37,-122(旧金山附近的某个地方),则将在 37,37(土耳其南部的某个地方)绘制线。

由于您实际上并未将地图定位在错误的位置(您正在寻找“正确”位置的线),因此永远不会调用viewForOverlay,因为地图仅在可能覆盖时才调用它可见。


将该行更改为:

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

或者简单地说:

pointsToUse[i] = an.coordinate;


正如 James Frost 在 cmets 中提到的那样,从 iOS 7 开始,您应该使用 rendererForOverlay 而不是 viewForOverlay 尽管如果 rendererForOverlay 尚未实现,地图视图在 iOS 7 中仍将调用 viewForOverlay。虽然这不会阻止您的叠加层在当前情况下显示,但您应该实现新的委托方法以及旧的委托方法(如果 iOS 7 应用程序也将在 iOS 6 或更早版本上运行)。


另一个重要但不相关的问题是您不必要地创建了多个重叠的叠加层。在drawRoute 中,由于您正在创建的叠加层包括所有 位置,因此您应该在添加新叠加层之前删除所有现有的叠加层。否则,地图以位置 0 到 1 的覆盖图、位置 0 到位置 2 的覆盖图、位置 0 到位置 3 的覆盖图等结束。之前的覆盖图不明显可见,因为它们具有相同的颜色和线条宽度。在addOverlay 行之前,放:

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

【讨论】:

  • 我会尝试并给你一些反馈,谢谢!
  • 工作就像一个魅力!你太棒了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-23
  • 2017-08-27
  • 2012-08-09
  • 2013-09-04
  • 2011-05-13
  • 2019-06-01
相关资源
最近更新 更多