0

I'm working on a mobile App using Xamarin Forms, I'm facing an issue that is working as expected on Android but not on IOS, I have a share button that will call the built-in share of the working platform passing the title and uri, however on IOS this functionality seems not working as expected, I don’t know if it’s slow or had other problem, so that you have to hit the share icon many time to get the share popup displayed (again this is working very good on Android).

Please Advise, The following is the code:

<StackLayout Grid.Column="2" Grid.ColumnSpan="2" Spacing="0" Margin="0,5,13,0">
   <StackLayout.GestureRecognizers>
      <TapGestureRecognizer Tapped="ImageButton_Clicked"/>
   </StackLayout.GestureRecognizers>
   <Image Source="export" HeightRequest="27" WidthRequest="20" VerticalOptions="Center" HorizontalOptions="End" Margin="0,0,0,0"/>
</StackLayout>
private async void ImageButton_Clicked(object sender, System.EventArgs e)
{
       await Share.RequestAsync(new ShareTextRequest
       {
           Uri = "http://myurl",
           Title = "My Title"
       });
}

In additional to my previous question I will share the whole xaml code hop this may give a clear view:

Xaml Code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:Helpers="clr-namespace:StandardsView.Helper"
             xmlns:telerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
             xmlns:telerikListView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls"
             xmlns:local="clr-namespace:StandardsView.Views"
             xmlns:telerikPrimitives="clr-namespace:Telerik.XamarinForms.Primitives;assembly=Telerik.XamarinForms.Primitives"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="StandardsView.Views.PreviewStandard"
             x:Name="parent"
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
             ios:Page.UseSafeArea="False"
             NavigationPage.HasNavigationBar="False"
             BackgroundImageSource="{Binding AppModel.BackgroundImage}"
             IsEnabled="{Binding AppModel.IsBusy, Converter={Helpers:InverseBoolConverter}}">
    <Grid RowSpacing="0" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <telerikDataControls:RadListView x:Name="listView" Margin="10,0,0,0" SelectionMode="None" ItemsSource="{Binding AppModel.Benchmarks}"  HeaderTemplate="{StaticResource ListHeaderTemplate}" FooterTemplate="{StaticResource ListFooterTemplate}">
            <telerikDataControls:RadListView.ItemStyle>
                <telerikListView:ListViewItemStyle BackgroundColor="Transparent" BorderLocation="None" BorderWidth="0" BorderColor="Transparent" />
            </telerikDataControls:RadListView.ItemStyle>
            <telerikDataControls:RadListView.SelectedItemStyle>
                <telerikListView:ListViewItemStyle BackgroundColor="Transparent" />
            </telerikDataControls:RadListView.SelectedItemStyle>
            <telerikDataControls:RadListView.ItemTemplate>
                <DataTemplate>
                    <telerikListView:ListViewTemplateCell>
                        <telerikListView:ListViewTemplateCell.View>
                            <StackLayout Padding="0" Spacing="0" BackgroundColor="Transparent" Margin="0,0,0,10">
                                <telerikPrimitives:RadBorder CornerRadius="15, 15, 0, 0" Padding="0" Margin="0,0,12,0">
                                    <telerikPrimitives:RadBorder.Triggers>
                                        <DataTrigger TargetType="telerikPrimitives:RadBorder" Binding="{Binding ResourceCount}" Value="0">
                                            <Setter Property="CornerRadius" Value="15"/>
                                        </DataTrigger>
                                    </telerikPrimitives:RadBorder.Triggers>
                                    <Grid BackgroundColor="White">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="19"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="60"/>
                                            <ColumnDefinition Width="10"/>
                                        </Grid.ColumnDefinitions>
                                        <StackLayout Grid.Column="2" Grid.ColumnSpan="2" Spacing="0" Margin="0,5,13,0">
                                            <StackLayout.GestureRecognizers>
                                                <TapGestureRecognizer Command="{Binding ShareCommand}" />
                                            </StackLayout.GestureRecognizers>
                                            <Image Source="export" HeightRequest="27" WidthRequest="20" VerticalOptions="Center" HorizontalOptions="End" />
                                        </StackLayout>
                                        <StackLayout Grid.Column="1" Grid.ColumnSpan="2" Padding="0,0,0,10">
                                            <Grid Margin="0">
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="130"/>
                                                    <ColumnDefinition Width="*"/>
                                                </Grid.ColumnDefinitions>
                                                <Grid.RowDefinitions>
                                                    <RowDefinition Height="Auto"/>
                                                </Grid.RowDefinitions>
                                                <BoxView BackgroundColor="{StaticResource CPALMS_BlueGreen}" CornerRadius="0,0,5,5" HeightRequest="22" WidthRequest="130"/>
                                                <Label Text="{Binding Code}" Style="{StaticResource BrowseItemTitle}" />
                                            </Grid>
                                            <Label MinimumHeightRequest="50" Style="{StaticResource BrowseItemDescription16}" Text="{Binding Description}" Margin="0,7,0,7" />
                                            <StackLayout>
                                                <StackLayout.Triggers>
                                                    <DataTrigger TargetType="StackLayout" Binding="{Binding Remarks}" Value="">
                                                        <Setter Property="IsVisible" Value="False"/>
                                                    </DataTrigger>
                                                </StackLayout.Triggers>
                                                <BoxView HeightRequest="1" BackgroundColor="{StaticResource CPALMS_BlueGreen}" ></BoxView>
                                                <Label Style="{StaticResource StdClarificationsTitleLabel}" Text="Clarifications" />
                                                <Label Style="{StaticResource StdClarificationsLabel}" Text="{Binding Remarks}" />
                                            </StackLayout>
                                            <BoxView HeightRequest="1" BackgroundColor="{StaticResource CPALMS_BlueGreen}" ></BoxView>
                                            <Label Style="{StaticResource StdInfoLabel}">
                                                <Label.Triggers>
                                                    <DataTrigger TargetType="Label" Binding="{Binding ContentComplexityDescription}" Value="">
                                                        <Setter Property="IsVisible" Value="False"/>
                                                    </DataTrigger>
                                                </Label.Triggers>
                                                <Label.FormattedText>
                                                    <FormattedString>
                                                        <Span Text="Content Complexity: " />
                                                        <Span Text="{Binding ContentComplexityDescription}"/>
                                                    </FormattedString>
                                                </Label.FormattedText>
                                            </Label>
                                            <Label Style="{StaticResource StdInfoLabel}">
                                                <Label.Triggers>
                                                    <DataTrigger TargetType="Label" Binding="{Binding DateStandard}" Value="">
                                                        <Setter Property="IsVisible" Value="False"/>
                                                    </DataTrigger>
                                                </Label.Triggers>
                                                <Label.FormattedText>
                                                    <FormattedString>
                                                        <Span Text="Date Adopted/Revised: " />
                                                        <Span Text="{Binding DateStandard}"/>
                                                    </FormattedString>
                                                </Label.FormattedText>
                                            </Label>

                                        </StackLayout>
                                    </Grid>
                                </telerikPrimitives:RadBorder>
                                <telerikPrimitives:RadBorder CornerRadius="0, 0, 15, 15" Padding="0" Margin="0,-2,12,0">
                                    <telerikPrimitives:RadBorder.Triggers>
                                        <DataTrigger TargetType="telerikPrimitives:RadBorder" Binding="{Binding ResourceCount}" Value="0">
                                            <Setter Property="IsVisible" Value="false"/>
                                        </DataTrigger>
                                    </telerikPrimitives:RadBorder.Triggers>
                                    <Grid BackgroundColor="#F29A33" Padding="0,5,0,5">
                                        <Grid.GestureRecognizers>
                                            <TapGestureRecognizer Tapped="PreviewStd" />
                                        </Grid.GestureRecognizers>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="19"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="40"/>
                                            <ColumnDefinition Width="7"/>
                                        </Grid.ColumnDefinitions>
                                        <StackLayout Grid.Column="1"  Padding="0,0,5,10">
                                            <StackLayout.GestureRecognizers>
                                                <TapGestureRecognizer Tapped="PreviewStd"/>
                                            </StackLayout.GestureRecognizers>
                                            <Label Style="{StaticResource previewRelatedResourceLabel}">
                                                <Label.GestureRecognizers>
                                                    <TapGestureRecognizer Tapped="PreviewStd"/>
                                                </Label.GestureRecognizers>
                                                <Label.FormattedText>
                                                    <FormattedString>
                                                        <Span Text="{Binding ResourceCount}" FontSize="{StaticResource LargeHeaderSize}" />
                                                        <Span Text="{Binding RelatedResourcesLabel}" />
                                                    </FormattedString>
                                                </Label.FormattedText>
                                            </Label>
                                        </StackLayout>
                                        <StackLayout Grid.Column="2" Spacing="0" Padding="0,5,0,0">
                                            <StackLayout.GestureRecognizers>
                                                <TapGestureRecognizer Tapped="PreviewStd"/>
                                            </StackLayout.GestureRecognizers>
                                            <Image Source="rightarrow" HeightRequest="31" WidthRequest="31" VerticalOptions="Center" HorizontalOptions="End" Margin="0,0,0,0"/>
                                        </StackLayout>
                                    </Grid>
                                </telerikPrimitives:RadBorder>
                            </StackLayout>
                        </telerikListView:ListViewTemplateCell.View>
                    </telerikListView:ListViewTemplateCell>
                </DataTemplate>
            </telerikDataControls:RadListView.ItemTemplate>
            <telerikDataControls:RadListView.LayoutDefinition>
                <telerikListView:ListViewLinearLayout  VerticalItemSpacing="4"/>
            </telerikDataControls:RadListView.LayoutDefinition>
        </telerikDataControls:RadListView>
        <local:NavigationBar Grid.Row="1" prism:ViewModelLocator.AutowirePartialView="{x:Reference parent}" VerticalOptions="End"/>
        <local:LoadingPanel  Grid.RowSpan="2" prism:ViewModelLocator.AutowirePartialView="{x:Reference parent}" IsVisible="{Binding AppModel.IsBusy}"/>
    </Grid>
</ContentPage>

Model Class:

using Prism.Commands;

namespace StandardsView.Models.Entities
{
    public class StandardViewModel
    {
        public virtual int ID { get; set; }
        public virtual string Description { get; set; }
        public virtual string Code { get; set; }
        public virtual string DateStandard { get; set; }
        public virtual string Status { get; set; }

        public virtual string SubjectAreaName { get; set; }
        public virtual string GradeLevelCode { get; set; }

        public virtual string DomainAlias { get; set; }
        public virtual string DomainDescription { get; set; }

        public virtual string IdeaAlias { get; set; }
        public virtual string IdeaTitle { get; set; }
        public virtual int ResourceCount { get; set; }

        public virtual string Remarks { get; set; }

        public virtual string RelatedResourcesLabel { get; set; }

        public virtual string ContentComplexityDescription { get; set; }

        public DelegateCommand ShareCommand { get; set; }

    }
}

ViewModel:

using Prism.Commands;
using Prism.Navigation;
using System;
using Xamarin.Forms;
using Xamarin.Essentials;

namespace StandardsView.ViewModels
{
    public class PreviewStandardViewModel : ViewModelBase
    {
        public DelegateCommand PreviewCommand { get; }

        public PreviewStandardViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            App.GlobalAppModel.Benchmarks[0].ShareCommand = new DelegateCommand(() => ShareBenchmark());
            AppModel = App.GlobalAppModel;
            ShowBackButton = true;
            Instructions = "Benchmark details";
            PreviewCommand = new DelegateCommand(() => PreviewBenchmark());

        }

        private void PreviewBenchmark()
        {
            Launcher.OpenAsync(new Uri(string.Format(Constants.previewStandardUrl, App.GlobalAppModel.Benchmarks[0].ID)));
        }

        private void ShareBenchmark()
        {
            Device.BeginInvokeOnMainThread(async () =>
            {
                string strUri = string.Format(Constants.previewStandardUrl, App.GlobalAppModel.Benchmarks[0].ID);
                string strTitle = App.GlobalAppModel.Benchmarks[0].Code;
                string strText = App.GlobalAppModel.Benchmarks[0].Code + " - " + App.GlobalAppModel.Benchmarks[0].Description;
                await Share.RequestAsync(new ShareTextRequest
                {
                    Uri = strUri,
                    Title = strTitle,
                    Text = strText
                });
            });
        }
    }
}

Also there is an important info that I have to mention, in the code above you will see in the Model class a DelegateCommand declared inside it and on the ViewModel class you will see that this delegate is assigned to the method, well this is the last of my tries and before that try I was using:

<StackLayout Grid.Column="2" Grid.ColumnSpan="2" Spacing="0" Margin="0,5,13,0">
   <StackLayout.GestureRecognizers>
      <TapGestureRecognizer Tapped="ImageButton_Clicked"/>
   </StackLayout.GestureRecognizers>
   <Image Source="export" HeightRequest="27" WidthRequest="20" VerticalOptions="Center" HorizontalOptions="End" Margin="0,0,0,0"/>
</StackLayout>
private void ImageButton_Clicked(object sender, System.EventArgs e)
{
       Device.BeginInvokeOnMainThread(async () =>
            {
                string strUri = string.Format(Constants.previewStandardUrl, App.GlobalAppModel.Benchmarks[0].ID);
                string strTitle = App.GlobalAppModel.Benchmarks[0].Code;
                string strText = App.GlobalAppModel.Benchmarks[0].Code + " - " + App.GlobalAppModel.Benchmarks[0].Description;
                await Share.RequestAsync(new ShareTextRequest
                {
                    Uri = strUri,
                    Title = strTitle,
                    Text = strText
                });
            });
}

So all of those cases lead to the same behavior, I shared now all my code hopefully this will help to understand my problem better.

Fadl Assaad
  • 99
  • 13
  • If its async method then hitting only once will work. Until that you can disable the button or show spinner or something to prevent tapping multiple times until first request completes! Being slow on iOS I never had that issue. – N Subedi Dec 03 '19 at 16:17
  • Thanks for your comment @NirmalSubedi as per multiple touch currently and for test purpose I touch only once and wait and nothing happened and then I tried again and wait... 6 times so the share popup appeared, I don't know why this slow on iPad and iPhone, as I said I'm not sure if this is a slow problem or another unknown problem form me, it's a simple code nothing crazy on it, and it worked like a sharm on Android devices. Any idea? Can you please share a working code so that I can compare with mine? – Fadl Assaad Dec 04 '19 at 07:01

1 Answers1

1

1.Please check if there is any other View overlap your StackLayout. The area which is overlapped by other view won't response to the TapGestureRecognizer.

2.Run the Share code in Main thread:

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{

    Device.BeginInvokeOnMainThread(async () => {
        await Share.RequestAsync(new ShareTextRequest
        {
            Uri = "http://myurl",
            Title = "My Title"
        });
    });
}

I created a new project and add your codes there, the share window works well in iOS side.

nevermore
  • 15,432
  • 1
  • 12
  • 30
  • Thanks Jack, I tried your provided code and I'm still getting same behavior, I looked carefully to your first point as well, there is nothing overlap my StackLayout and actually I tried 6 time to hit the share icon and wait till the popup appear in the time that on Android on first touch the share appeared. I agree that maybe something on my page causing this, I will update my first question and add the whole code of my xaml so that you can look at it knowing that I have other tap event in the bottom that will lunch the browser and it's working well on IOS, I will add info to my first question – Fadl Assaad Dec 04 '19 at 07:43
  • @FadlAssaad Ok, I will check it once you update the code. – nevermore Dec 04 '19 at 07:46
  • I updated my code, please check and let me know your thought. – Fadl Assaad Dec 04 '19 at 07:59
  • @FadlAssaad What I would do first is add a breakpoint in the ShareBenchmark method and then debug it to see if the breakpoint hit when you click the image or the stacklayout. Then if it hits, wait until the share window popup. If it not hit, the problem is in your layout. I would replace the image with a boxView which has a red background color and test again, then we can see the actual area of the boxView and then click it to see if the ShareBenchmark method triggered. – nevermore Dec 04 '19 at 08:10
  • Thanks for your hint I will try it, the issue is that the emulator is not running the app on mac, so I have each time to push new test version to TestFlight and check it on iPad/iPhone I will make some research to check why the emulator stuck on the splash screen knowing that I created a very basic app with default mainpage having label and also that app is not opening on emulator, so for that I'm not able to debug, anyway I will check if I can solve that problem and will let you know. – Fadl Assaad Dec 04 '19 at 08:21
  • @FadlAssaad If you can't debug right now, you can add some other event like display an alert(Remember to display it in main thread), change some color or some thing that you are sure that will be triggered. – nevermore Dec 04 '19 at 08:26
  • you are correct, point 1 of your answer is the issue, I have in the xaml code the following: the mistake here is the Grid.ColumnSpan this is added by mistake so that items of column 1 are overlap column 2, I don't know how come it's working on Android, anyway thanks for your hint and I will mark your answer as the correct answer. – Fadl Assaad Dec 04 '19 at 13:20