Xamarin表示Geolocator IOS

时间:2017-06-17 17:45:22

标签: c# xamarin.ios xamarin.android xamarin.forms

我正在处理我正在处理的项目的问题。我最近开始学习C#并成功构建了Xamarin Forms的基本程序。

我正潜入一个相当大的项目并继续学习。

我目前遇到的问题是生成一个以设备当前位置为中心的地图页面。我已经将问题缩小到我所认为的位置,一旦获得该位置没有被保存到我已声明的变量中,以便我可以用另一种方法访问它。

public partial class MapPage : ContentPage
{

        public static double latitude;
        public static double longitude;

    public MapPage()
    {
        InitializeComponent();
        GetCurrentLocation();

        var map = new Map(MapSpan.FromCenterAndRadius(
            new Position(latitude, longitude), Distance.FromMiles(.3)))
        {
            MapType = MapType.Street,
            IsShowingUser = true,
            HeightRequest = 100,
            WidthRequest = 960,
            VerticalOptions = LayoutOptions.FillAndExpand,
            HasScrollEnabled = true,
            HasZoomEnabled = true
        };

        var stack = new StackLayout { Spacing = 0 };
        stack.Children.Add(map);
        Content = stack;
    }


    private static async void GetCurrentLocation()
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;

        var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);

        latitude = position.Latitude;
        longitude = position.Longitude;
    }
}

当使用上面的代码显示地图时,它接收纬度和经度(0,0)。我已经使用断点和调试验证了纬度和经度被检索并存储在"位置"但是我并不相信它存储在我的纬度和经度变量中。

知道我在这里缺少什么吗?

2 个答案:

答案 0 :(得分:0)

public async override void OnAppearing()
{
    var pos = await GetCurrentLocation();

    var map = new Map(MapSpan.FromCenterAndRadius(
        pos, Distance.FromMiles(.3)))
    {
        MapType = MapType.Street,
        IsShowingUser = true,
        HeightRequest = 100,
        WidthRequest = 960,
        VerticalOptions = LayoutOptions.FillAndExpand,
        HasScrollEnabled = true,
        HasZoomEnabled = true
    };

    var stack = new StackLayout { Spacing = 0 };
    stack.Children.Add(map);
    Content = stack;
}

private async Position GetCurrentLocation()
{
    var locator = CrossGeolocator.Current;
    locator.DesiredAccuracy = 50;

    var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);

    return position;
}

答案 1 :(得分:0)

您的代码中有应该注意的几件事

  • 检索位置的方法'GetCurrentLocation()'是异步的。如果失败,您的应用程序将失败。你应该少用这个方法中的try {} catch {}。 Personaly,为了便于阅读,我还为异步方法添加了“Async”后缀(即:GetCurrentLoactionAsync())。

  • 接下来,您将从构造函数中调用“异步”方法。但是在构造函数中,您不能等待异步方法(等待结果)。这就是为什么你总是有一个空位。你不应该从这里调用这个方法。

  • 如提到的@Jason,您可以覆盖'OnAppearing()'方法来加载数据。这是一个更好的地方。但请注意使用'await'关键字并在try / catch块中调用该方法,因为'OnAppearing()'不会返回任务。

  • 最后,我建议您在XAML代码部分中创建地图(因此地图已经存在,并且在加载位置之前不会有空白页面)。然后在OnAppearing()中使用posistion初始化地图(它可能会通过重新定位在地图上生成动画。我认为这更令人愉快;)。

XAML部分:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="MediaSample.MapPage">
<ContentPage.Content>
    <Grid>

        <!-- your map object -->
        <Map x:Name="uiMap" />

        <!-- whatever you want -->

    </Grid>
</ContentPage.Content>

部分代码:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MapPage : ContentPage
{
    public MapPage()
    {
        InitializeComponent();
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();

        try
        {
            // get your position
            var centerPos = await GetCurrentLocation();

            // init map => center on the position
            uiMap.MoveToRegion(MapSpan.FromCenterAndRadius(centerPos, Distance.FromMiles(.3)).WithZoom(20));
        }
        catch(Exception e)
        {
            // notify user here
            // log exception
        }
    }

    private async Task<Position> GetCurrentLocation()
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;

        var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);

        return position;
    }
}