Как добавить кнопку местоположения на карты форм xamarin - PullRequest
0 голосов
/ 06 августа 2020

Я реализовал XF Maps и добавил разрешения из XF.Essentials. На ANdroid все в порядке, но на iOS я не вижу кнопку местоположения после того, как я нажал «Утвердить» для разрешений?

Что еще я нужно добавить, чтобы увидеть кнопку местоположения (геолокацию пользователя)?

...
        private async void GetPermissions()
        {
            var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
            if (status != PermissionStatus.Granted)
            { 
                status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
            }
            if (status != PermissionStatus.Granted)
            {
                await Shell.Current.DisplayAlert("Permission Denied", "We Need to access your Location. But it is not granted", "OK");
            }
        }
...

my iOS renderer

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace OperaMobile.iOS.Renderers
{
    public class CustomMapRenderer : MapRenderer
    {
        UIStackView customPinView;
        ObservableCollection<CustomPin> customPins;

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                var nativeMap = Control as MKMapView;
                nativeMap.GetViewForAnnotation = null;
                nativeMap.CalloutAccessoryControlTapped -= OnCalloutAccessoryControlTapped;
                nativeMap.DidSelectAnnotationView -= OnDidSelectAnnotationView;
                nativeMap.DidDeselectAnnotationView -= OnDidDeselectAnnotationView;
            }

            if (e.NewElement != null)
            {
                var formsMap = (CustomMap)e.NewElement;
                var nativeMap = Control as MKMapView;
                customPins = formsMap.CustomPins;

                nativeMap.GetViewForAnnotation = GetViewForAnnotation;
                nativeMap.CalloutAccessoryControlTapped += OnCalloutAccessoryControlTapped;
                nativeMap.DidSelectAnnotationView += OnDidSelectAnnotationView;
                nativeMap.DidDeselectAnnotationView += OnDidDeselectAnnotationView;
            }
        }

        protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
        {
            MKAnnotationView annotationView = null;

            if (annotation is MKUserLocation)
                return null;

            var customPin = GetCustomPin(annotation as MKPointAnnotation);
            if (customPin == null)
            {
                throw new Exception("Custom pin not found");
            }

            annotationView = mapView.DequeueReusableAnnotation(customPin.Label);
            if (annotationView == null)
            {
                annotationView = new CustomMKAnnotationView(annotation, customPin.Label);
                annotationView.Image = UIImage.FromFile("pin.png");
                annotationView.CalloutOffset = new CGPoint(0, 0);

                UIImageView uIImageView = new UIImageView(UIImage.FromFile("monkey.png"));
                uIImageView.Frame = new CGRect(0, 0, 75, 100);
                annotationView.LeftCalloutAccessoryView = uIImageView;

                //annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
                //annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
                ((CustomMKAnnotationView)annotationView).Name = customPin.Label;
                //((CustomMKAnnotationView)annotationView).Url = customPin.Url;

                customPinView = new UIStackView();

                foreach (var item in customPin.InfoBox.DetailsObjectInfos)
                {
                    var label = new UILabel();
                    label.Text = item.BoldLabelTitle + item.LabelValue;
                    label.BackgroundColor = UIColor.White;
                    label.Font.WithSize(36);
                    customPinView.AddArrangedSubview(label);
                }
            
                customPinView.Frame = new CGRect(0, 0, 300, 84);
                customPinView.Axis = UILayoutConstraintAxis.Vertical;
                customPinView.Distribution = UIStackViewDistribution.EqualSpacing;
                customPinView.Spacing = 1;
                customPinView.Alignment = UIStackViewAlignment.Fill;
                annotationView.DetailCalloutAccessoryView = customPinView;

                UITapGestureRecognizer tapGestureRecognizer = new
        UITapGestureRecognizer((gesture) =>
        {

                        Shell.Current.GoToAsync(Routes.ObjectParametersPage);

        });
                annotationView.DetailCalloutAccessoryView.AddGestureRecognizer(tapGestureRecognizer);

            }
            annotationView.CanShowCallout = true;

            return annotationView;
        }

        protected virtual void OnCalloutAccessoryControlTapped(object sender, MKMapViewAccessoryTappedEventArgs e)
        {
            Shell.Current.GoToAsync(Routes.ObjectParametersPage);
            //(App.Current as App).NavigationPage.Navigation.PushAsync(new ContentPage());
        }

        void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
        {
            CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
            
        }

        void OnDidDeselectAnnotationView(object sender, MKAnnotationViewEventArgs e)
        {
            if (!e.View.Selected)
            {
                customPinView.RemoveFromSuperview();
                customPinView.Dispose();
                customPinView = null;
            }
        }

        CustomPin GetCustomPin(MKPointAnnotation annotation)
        {
            var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
            foreach (var pin in customPins)
            {
                if (pin.Position == position)
                {
                    return pin;
                }
            }
            return null;
        }
}}

1 Ответ

1 голос
/ 07 августа 2020

Не знаете, как добавить кнопку местоположения в свой проект, возможно, вы можете добавить настраиваемый ImageButton со значком местоположения в Xaml .

Xaml код:

<RelativeLayout>
    <local:CustomMap x:Name="customMap" 
                     IsShowingUser="True"
                     MapType="Street"
                     IsVisible="true"
                     RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
                         Property=Width,
                         Factor=0,
                         Constant=0}"
                     RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                         Property=Height,
                         Factor=0,
                         Constant=0}"
                     RelativeLayout.WidthConstraint="{ConstraintExpression
        Type=RelativeToParent,Property=Width,Factor=1,Constant=0}"
                     RelativeLayout.HeightConstraint="{ConstraintExpression
        Type=RelativeToParent,Property=Height,Factor=1,Constant=0}" />
    <ImageButton Source="location.png"
            Clicked="Button_Clicked"
            RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
                         Property=Width,
                         Factor=0.6,
                         Constant=100}"
            RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                         Property=Height,
                         Factor=0.8,
                         Constant=80}" />
</RelativeLayout>

The contentpage.cs:

private async void Button_Clicked(object sender, System.EventArgs e)
{
    var request = new GeolocationRequest(GeolocationAccuracy.Medium);
    var location = await Geolocation.GetLocationAsync(request);

    if (location != null)
    {
        Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
 
    }
       
    customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(location.Latitude, -location.Longitude), Distance.FromMiles(1.0)));
}

Эффект:

enter image description here

==================================Update #1=================================

In xamarin forms , you can hide the xaml location button only in Android , then iOS will show the xaml location button.

protected override void OnAppearing()
{
    base.OnAppearing();
    if(Device.RuntimePlatform == "Android")
    {
        LocationButton.IsVisible = false;
    }
}

The LocationButton is defined in Xaml :

==================================Update #2=================================

If need to test location in ios simulator, you need to choose the location manually. Clicking settings of simulatoras follow:

enter image description here

Choose a location:

введите описание изображения здесь

...