я пытаюсь нарисовать путь на карте, по которому шел пользователь. Он отлично работает на Android, но ios просто рисует в начале маленькую линию. После срабатывания OnElementPropertyChanged ничего не рисуется.
RouteCoordinates создаются в классе Map на основе CustomMap как BindableProperties. Я думаю, что мой измененный метод свойства не может достичь правого слоя или потока отображения.
Мой пользовательский рендерер для IOS:
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PawsApp.iOS.Renderers
{
public class CustomMapRenderer : MapRenderer
{
MKPolylineRenderer polylineRenderer;
CustomMap formsMap;
MKMapView nativeMap;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
if (nativeMap != null)
{
nativeMap.RemoveOverlays(nativeMap.Overlays);
nativeMap.OverlayRenderer = null;
polylineRenderer = null;
}
}
if (e.NewElement != null)
{
formsMap = (CustomMap)e.NewElement;
nativeMap = Control as MKMapView;
UpdatePolyLine();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
//if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
if ((e.PropertyName == "RouteCoordinates" || e.PropertyName == "VisibleRegion"))
{
formsMap = (CustomMap)sender;
nativeMap = Control as MKMapView;
UpdatePolyLine();
}
}
private void UpdatePolyLine()
{
//var nativeMap = Control as MKMapView;
nativeMap.OverlayRenderer = GetOverlayRenderer;
CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];
int index = 0;
foreach (var position in formsMap.RouteCoordinates)
{
coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
index++;
}
var routeOverlay = MKPolyline.FromCoordinates(coords);
nativeMap.AddOverlay(routeOverlay);
}
//[Foundation.Export("mapView:rendererForOverlay:")]
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
{
if (polylineRenderer == null)
{
var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
//var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as MKPolyline;
polylineRenderer = new MKPolylineRenderer(overlay as MKPolyline)
{
FillColor = UIColor.Yellow,
StrokeColor = UIColor.Red,
LineWidth = 3,
Alpha = 0.4f
};
}
return polylineRenderer;
}
}
}
Привет, да, я сделал. OnElementPropertyChanged срабатывал, и UpdatePolyLine работал, но ничего не рисовал. @JackHua-MSFT
Попробовав это на своей стороне, я обнаружил, что если вы хотите обновить полилинию на карте в iOS, вам необходимо:
polyline
;ativeMap.OverlayRenderer
каждый раз.Я изменил код клиентского рендерера следующим образом:
public class CustomMapRenderer : MapRenderer
{
MKPolylineRenderer polylineRenderer;
CustomMap formsMap;
MKMapView nativeMap;
MKPolyline polyline;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
if (nativeMap != null)
{
nativeMap.RemoveOverlays(nativeMap.Overlays);
nativeMap.OverlayRenderer = null;
polylineRenderer = null;
}
}
if (e.NewElement != null)
{
formsMap = (CustomMap)e.NewElement;
nativeMap = Control as MKMapView;
UpdatePolyLine();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (this.Element == null || this.Control == null)
return;
//if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
if ((e.PropertyName == "RouteCoordinates" || e.PropertyName == "VisibleRegion"))
{
formsMap = (CustomMap)sender;
nativeMap = Control as MKMapView;
UpdatePolyLine();
}
}
private void UpdatePolyLine()
{
//var nativeMap = Control as MKMapView;
if (polyline != null)
{
nativeMap.RemoveOverlay(polyline);
polyline.Dispose();
}
nativeMap.OverlayRenderer = GetOverlayRenderer;
CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];
int index = 0;
foreach (var position in formsMap.RouteCoordinates)
{
coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
index++;
}
var routeOverlay = MKPolyline.FromCoordinates(coords);
nativeMap.AddOverlay(routeOverlay);
polyline = routeOverlay;
}
//[Foundation.Export("mapView:rendererForOverlay:")]
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)
{
if (polylineRenderer != null)
{
polylineRenderer = null;
}
var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;
//var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as MKPolyline;
polylineRenderer = new MKPolylineRenderer(overlay as MKPolyline)
{
FillColor = UIColor.Yellow,
StrokeColor = UIColor.Red,
LineWidth = 3,
Alpha = 0.4f
};
return polylineRenderer;
}
}
И в проекте xamarin.forms каждый раз сбрасывайте customMap.RouteCoordinates
:
Device.StartTimer(TimeSpan.FromSeconds(3), () =>
{
Device.BeginInvokeOnMainThread(() =>
{
a -= 0.000321;
b += 0.000222;
customMap.RouteCoordinates = new List<Position>
{
new Position (37.797534, -122.401827),
new Position(37.797510, -122.402060),
new Position(37.790269, -122.400589),
new Position(37.790265, -122.400474),
new Position(37.790228, -122.400391),
new Position(37.790126, -122.400360),
new Position(37.789250, -122.401451),
new Position(a, b)
};
});
return true;
});
Я также загружаю свою демку здесь, и вы можете ее проверить. Дайте мне знать, если это работает.
Ты настоящий герой! Спасибо большое!! Как вы это поняли?
Вы когда-нибудь добавляли точку останова в
OnElementPropertyChanged
, чтобы проверить, сработала ли она? Или срабатываетUpdatePolyLine
? И тогда вы могли бы узнать проблему.