Home > Back-end >  Xamarin.iOS: Share file sheet appears only for two seconds
Xamarin.iOS: Share file sheet appears only for two seconds

Time:05-20

Xamarin.Essentials provides a mechanism to share a local file. The typical use case:

await Share.RequestAsync(new ShareFileRequest
{
    Title = "Sharing a file...",
    File = new ShareFile(pathToLocalFile),
});

pathToLocalFile - contains absolute path to local file that has to be shared.

While this code works perfectly for Android, on iOS it does not work as expected.

On iOS "Share file" sheet appears only for a couple of seconds and just disappears.

How can I fix this issue?

CodePudding user response:

I inspected the Xamarin.Essentials sample, related to this functionality, and I came to the following conclusions.

ShareFileRequest class has PresentationSourceBounds that should be set to the bounds of the parent view element.

"Share file" functionality should be called from a visible view element, for example via clicking a button on the page. Calling this functionality from a menu item does not work.

So, I've created a page, and in page xaml, declared the button like that:

<Button Text="Click here to share the file..." 
        Command="{Binding ShareLocalFileCommand}" 
        CommandParameter="{Binding Source={RelativeSource Self}}" />

In the page view model I declared ShareLocalFileCommand this way:

public Command<View> ShareLocalFileCommand { get; }

In the view model constructor I've initialized ShareLocalFileCommand property like this:

ShareLocalFileCommand = new Command<View>(ExecuteShareLocalFileCommandAsync);

And the relevant method has been implemented like that:

private async void ExecuteShareLocalFileCommandAsync(View viewElement)
{
    await Share.RequestAsync(new ShareFileRequest
    {
        Title = "Sharing local file...",
        File = new ShareFile(LocalFilePath), // LocalFilePath contains path to local file to be shared
        PresentationSourceBounds = GetAbsoluteBounds(viewElement)
    });
}


private static System.Drawing.Rectangle GetAbsoluteBounds(View element)
{
    Element looper = element;

    var absoluteX = element.X   element.Margin.Top;
    var absoluteY = element.Y   element.Margin.Left;

    while (looper.Parent != null)
    {
        looper = looper.Parent;
        if (looper is View view)
        {
            absoluteX  = view.X   view.Margin.Top;
            absoluteY  = view.Y   view.Margin.Left;
        }
    }

    return new System.Drawing.Rectangle((int)absoluteX, (int)absoluteY, (int)element.Width, (int)element.Height);
}

Please note, between your click on the button and calling await Share.RequestAsync() there should not be any view elements that appear and disappear, like confirmation dialogs, etc etc. Otherwise viewElement parameter will be passed as null.

  • Related