我想以 xamarin 形式在 IOS 地图上制作两个注释视图,以便为 Tracking 平台制作一个重播页面。我已经在 C# 中完成了所有代码,在 IOS 自定义地图渲染器中(使用代码隐藏)。我被困在如何添加倒数第二个注释视图图像(箭头图像)上,在最后一个注释中,我正在添加汽车图标。
下面给出了 iOS 的自定义渲染器代码。 iOS 公共类 CustomMapRenderer : MapRenderer { private CustomMap _formsMap;
public MKMapView ExtMap { get; private set; }
List<CustomPin> customPins;
UIView customPinView;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
try
{
if (e.OldElement != null)
{
//var nativeMap = Control as MKMapView;
MKMapView nativeMap = new MKMapView();
if (nativeMap != null)
{
nativeMap.RemoveAnnotations(nativeMap.Annotations);
nativeMap.GetViewForAnnotation = null;
nativeMap.DidSelectAnnotationView -= NativeMap_DidSelectAnnotationView;
nativeMap.DidDeselectAnnotationView -= NativeMap_DidDeselectAnnotationView;
}
}
if (e.NewElement != null)
{
_formsMap = (ReplayMap)e.NewElement;
var nativeMap = Control as MKMapView;
ExtMap = Control as MKMapView;
customPins = _formsMap.CustomPins;
nativeMap.GetViewForAnnotation = GetViewForAnnotation;
nativeMap.DidSelectAnnotationView += NativeMap_DidSelectAnnotationView;
nativeMap.DidDeselectAnnotationView += NativeMap_DidDeselectAnnotationView;
}
}
catch (Exception ex)
{
LogManager.Log(ex);
}
}
private void NativeMap_DidDeselectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
if (!e.View.Selected)
{
customPinView.RemoveFromSuperview();
customPinView.Dispose();
customPinView = null;
}
}
private void NativeMap_DidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
try
{
var customView = e.View as CustomMKAnnotationView;
customPinView = new UIView();
var customPin = GetCustomPin(e.View.Annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
double lat = customView.Annotation.Coordinate.Latitude;
double lon = customView.Annotation.Coordinate.Longitude;
configureDetailView(customView, customPin);
}
catch (Exception ex)
{
LogManager.Log(ex);
}
}
CustomPin GetCustomPin(MKPointAnnotation annotation)
{
var position = new Xamarin.Forms.Maps.Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
CustomPin pin = new CustomPin();
try
{
if (customPins.Count > 0)
{
//Position Position = new Position(annotation.Position.Latitude, annotation.Position.Longitude);
pin = customPins.Where(x => x.Position == position).FirstOrDefault();
if (pin == null)
{
pin = customPins[0];
}
return pin;
//foreach (var pin in customPins)
//{
// if ((pin.Position.Latitude == position.Latitude) & (pin.Position.Longitude == position.Longitude))
// {
// return pin;
// }
//}
}
else
{
pin = customPins[0];
return pin;
}
}
catch (Exception ex)
{
}
return pin;
//if (Utility.customPins.Count > 1)
//{
// foreach (var pin in Utility.customPins)
// {
// if (pin.Position == position)
// {
// return pin;
// }
// }
//}
//else
//{
// return Utility.customPins[0];
//}
//return null;
}
void configureDetailView(MKAnnotationView annotationView, CustomPin pin)
{
int width = 150;
int height = 100;
var snapshotView = new UIView();
snapshotView.BackgroundColor = UIColor.White;
snapshotView.TranslatesAutoresizingMaskIntoConstraints = false;
NSDictionary views = NSDictionary.FromObjectAndKey(snapshotView, new NSString("snapshotView"));
snapshotView.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:[snapshotView(175)]", new NSLayoutFormatOptions(), null, views));
snapshotView.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:[snapshotView(150)]", new NSLayoutFormatOptions(), null, views));
var options = new MKMapSnapshotOptions();
options.Size = new CGSize(width, height);
//options.MapType = MKMapType.SatelliteFlyover;
// options.Camera = MKMapCamera.CameraLookingAtCenterCoordinate(annotationView.Annotation.Coordinate, 250, 65, 0);
var snapshotter = new MKMapSnapshotter(options);
snapshotter.Start((snapshot, error) =>
{
if (snapshot != null)
{
UIView markerInfoBackground = new UIView();
markerInfoBackground.BackgroundColor = UIColor.White;
// markerInfoBackground.Layer.ShadowColor = UIColor.Black;
// markerInfoBackground.Layer.ShadowOpacity = 1.5f;
// markerInfoBackground.Layer.ShadowRadius = 1.8f;
markerInfoBackground.Layer.ShadowOffset = new SizeF(0.5f, 0.5f);
markerInfoBackground.Add(imgLocation);
UILabel lblLocation = new UILabel(new RectangleF(25, 90, width, 30));
lblLocation.Text = getMapLocation(pin.Position.Latitude.ToString(), pin.Position.Longitude.ToString());
lblLocation.Font = UIFont.SystemFontOfSize(12.0F);
lblLocation.TextColor = UIColor.Gray;
lblLocation.LineBreakMode = UILineBreakMode.WordWrap;
lblLocation.Lines = 0;
markerInfoBackground.Add(lblLocation);
snapshotView.AddSubview(markerInfoBackground);
}
});
annotationView.DetailCalloutAccessoryView = snapshotView;
}
public string getMapLocation(string lat, string lng)
{
string baseUri = "KEY";
string location = "N/A";
string requestUri = string.Format(baseUri, lat, lng);
try
{
using (WebClient wc = new WebClient())
{
string result = wc.DownloadString(requestUri);
var xmlElm = XElement.Parse(result);
var status = (from elm in xmlElm.Descendants()
where
elm.Name == "status"
select elm).FirstOrDefault();
if (status.Value.ToLower() == "ok")
{
var res = (from elm in xmlElm.Descendants()
where
elm.Name == "formatted_address"
select elm).FirstOrDefault();
requestUri = res.Value;
location = res.Value;
}
}
}
catch (Exception) { }
return location;
}
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
MKAnnotationView annotationView1 = new MKAnnotationView();
try
{
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
CustomPin CustPin = new CustomPin();
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.ToString());
annotationView1 = new CustomMKAnnotationView(annotation, customPin.ToString());
OSAppTheme currentTheme = Xamarin.Forms.Application.Current.RequestedTheme;
foreach (CustomPin item in _formsMap.Pins)
{
var radians = item.Rotation + 90;
if (currentTheme == OSAppTheme.Dark)
{
annotationView.Image = RotateImage(UIImage.FromFile("car_icon_3.png"), Convert.ToSingle(radians));
annotationView1.Image = RotateImage(UIImage.FromFile("darkMode.png"), Convert.ToSingle(radians));
}
else
{
annotationView.Image = RotateImage(UIImage.FromFile("car_icon_1.png"), Convert.ToSingle(radians));
annotationView1.Image = RotateImage(UIImage.FromFile("Moving.png"), Convert.ToSingle(radians));
}
}
}
annotationView.CanShowCallout = true;
}
catch (Exception ex)
{
LogManager.Log(ex);
}
return annotationView;
}
public UIImage RotateImage(UIImage image, float degree)
{
float Radians = degree * (float)Math.PI / 180;
UIView view = new UIView(frame: new CGRect(0, 0, image.Size.Width, image.Size.Height));
CGAffineTransform t = CGAffineTransform.MakeRotation(Radians);
view.Transform = t;
CGSize size = view.Frame.Size;
UIGraphics.BeginImageContext(size);
CGContext context = UIGraphics.GetCurrentContext();
context.TranslateCTM(size.Width / 2, size.Height / 2);
context.RotateCTM(Radians);
context.ScaleCTM(1, -1);
context.DrawImage(new CGRect(-image.Size.Width / 2, -image.Size.Height / 2, image.Size.Width, image.Size.Height), image.CGImage);
UIImage imageCopy = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return imageCopy;
}
}