【问题标题】:Adding multiple polylines to an MKMapView (Xamarin)将多条折线添加到 MKMapView (Xamarin)
【发布时间】:2016-02-17 21:31:01
【问题描述】:

我正在扩展 @https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/maps/map-overlay/polyline/ 提供的示例,以向我的地图添加多条折线。

单条折线一切正常,但是当我添加第二条折线或在注释旁边添加折线时,GetOverlayRenderer 出错并显示错误

"Value cannot be null.Parameter name: polyline"

网上出错了:

polylineRenderer = new MKPolylineRenderer (overlay as MKPolyline);

当我查看覆盖对象时,它是:

{MapKit.MKOverlayWrapper}
BoundingMapRect: {{{62634939.7333333, 111606556.311973}, {745654.044444449, 848491.772016793}}}
Coordinate: {CoreLocation.CLLocationCoordinate2D}
Handle: 0x791ca560
Non-public members: 

我不明白为什么它适用于一条折线,但是当我向地图添加任何其他内容时,它会失败(也是第一次通过该方法)

这是发生错误的整个方法。我可以提供更多代码,但它只用一行就可以正常工作,而不是两行。 (我遍历一个对象列表...如果有 1,那很好。如果有 2,它会失败)。

MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlay)
    {

        if (polylineRenderer == null) {
            try
            {

            polylineRenderer = new MKPolylineRenderer (overlay as MKPolyline);
            polylineRenderer.FillColor = UIColor.Blue;
            polylineRenderer.StrokeColor = UIColor.Red;
            polylineRenderer.LineWidth = 3;
            polylineRenderer.Alpha = 0.4f;
            }
            catch (Exception ex) {
            }
        }
        return polylineRenderer;
    }

【问题讨论】:

  • 这可能是一个错误。如果你能把它拉上拉链寄过来,我会快速看一下?如果是这样,我的详细信息在我的个人资料中。
  • 我会直接给你发邮件,但是这里有其他感兴趣的人可以使用的链接...drive.google.com/file/d/0B5Tg3f2jpNBpbGFzVTFpZ2JQNFk/view这是一个稍微修改过的食谱版本(只是将 GPS 坐标移到我的区域进行演示与客户)。它适用于一个叠加层(注释掉 iOS 项目中 CustomMapRenderer.cs 的第 55 行)。如果添加第二个叠加层,它也不会显示。

标签: xamarin.ios mkmapview xamarin.forms mkpolyline


【解决方案1】:

对于代理,您对nativeMap.OverlayRenderer 的设置请记住,您添加的每个叠加层都会调用此设置。

当这个委托被调用时,它将被传递给它所关联的IMKOverlay

然后您可以返回之前存储的MKOverlayRenderer,或者创建一个新的。

当您尝试添加两个叠加层时,您的代码失败的原因是您尝试为 both 叠加层返回 same 渲染器,即polylineRenderer代码中的变量。

仅出于演示目的,我已将您的 GetOverlayRenderer 修改为以下内容。这不是一个好的设计,但说明了我在上面提出的观点。

当您现在运行此程序时,您将看到您的MKPolyline 之一为Red,另一个为Yellow 颜色。

在类范围内添加这个:-

private bool cblnIsTest = false;

然后将您的GetOverlayRenderer 修改为以下内容:-

MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlay)
{
    MKPolylineRenderer polylineRenderer2 = new MKPolylineRenderer(overlay as MKPolyline);

    if (!cblnIsTest)
    {
        cblnIsTest = true;
        //
        polylineRenderer2.StrokeColor = UIColor.Yellow;
    }
    else
    {
        polyline Renderer.StrokeColor = UIColor.Red;
    }
    polylineRenderer2.LineWidth = 3;
    polylineRenderer2.Alpha = 0.4f;
    //
    return polylineRenderer2;
}

更新 1:-

如上所述,代码不是很好的设计,只是为了说明一点。

是的 - 您可以重复使用 MKOverlayRenderer,但请记住,渲染器被分配给传递给您的委托的特定 IMKOverlay

您正在尝试为 multiple IMKOverlay 使用 same 渲染器。这是不可能的。

虽然您有一个现有的渲染器,但您不能将它分配给另一个 IMKOverlay,因为 MKOverlayRendererOverlay 属性是 只读,这就是原因。

HTH。

【讨论】:

  • 我会检查一下...从我对多个叠加层所做的其他一些阅读中,我认为重点是重用相同的 MKPolylineRenderer,而不是为每个叠加层创建一个新的。您是说每个叠加层(MKPolyline、MKCircle 等)都需要它自己的渲染器吗?如果是这样,它肯定解释了我的问题,但它与我认为我在其他地方读到的内容背道而驰(也许这是集成了一些可重用的渲染器?)。
  • @ChetatC2IT 我已经用更多信息更新了我的答案(请参阅更新 1)。
【解决方案2】:

请试试这个:

public override MKOverlayView GetViewForOverlay(MKMapView mapView, IMKOverlay overlay)
        {
            if (overlay is MKPolyline)
            {
                // return a view for the polygon
                MKPolyline l_polyline = overlay as MKPolyline;
                MKPolylineView l_polylineView = new MKPolylineView(l_polyline);
                MKPolylineRenderer l_polylineRenderer = new MKPolylineRenderer(l_polyline);

                l_polylineView.FillColor = UIColor.Blue;
                l_polylineView.StrokeColor = UIColor.Red;

                return l_polylineView;
            }

            return null;
        }

【讨论】:

  • 我已经尝试过了...永远不会超过 if 语句:“if (overlay is MKPolyline)” 我将从我正在处理的项目中提取所有代码进入一些非常小的东西(甚至可能是 Xamarin 提供的配方)并尝试,除非有人有更好的主意。
【解决方案3】:

@Pete,现在我明白了,这就成功了。对于我丑陋的演示,这就是我的目标。每次调用它都会创建一个新的渲染器......不是很好的形式,但它演示了您制作的代码 - 基本上我将我的渲染器从跨类的范围移动到每次请求时重新创建......不好的形式,我'将清理它以重用渲染器,但它完成了演示/理解的工作。

    MKOverlayRenderer GetOverlayRenderer (MKMapView mapView, IMKOverlay overlay)
    {
        //Moved the renderer here instead of being scoped at the class
        MKPolylineRenderer polylineRenderer= new MKPolylineRenderer (overlay as MKPolyline);
        polylineRenderer.FillColor = UIColor.Blue;
        polylineRenderer.StrokeColor = UIColor.Red;
        polylineRenderer.LineWidth = 3;
        polylineRenderer.Alpha = 0.4f;
        return polylineRenderer;
    }

他们来了!

【讨论】:

  • 原来这也是问题的一个重要部分 - 我还不确定这有什么关系,但我在我的真实应用程序中得到了一个 IMKOverlayWrapper 而不是 IMKOverlay ......我使用了下面的代码将其转换为实际的叠加层,然后具有我必要的“折线”属性。 var overlay = Runtime.GetNSObject(overlay.Handle) as MKOverlay; forums.xamarin.com/discussion/31616/…
【解决方案4】:

这里的最终结果是传递给方法的叠加层是某种包装器,您需要获取“句柄”属性才能获取实际的叠加层。

public override MKOverlayView GetViewForOverlay (MKMapView mapView, IMKOverlay overlayWrapper)
    {
    if (overlayWrapper != null) {
    var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as MKOverlay;
    // Do Overlay Functions here
    }

本文来源来自https://forums.xamarin.com/discussion/31616/what-is-mkoverlaywrapper-its-breaking-my-map-renderer

【讨论】:

    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    相关资源
    最近更新 更多