dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.06k stars 1.73k forks source link

iOS App Actions Navigation does not navigate to subpages correctly #16568

Open edgiardina opened 1 year ago

edgiardina commented 1 year ago

Description

If you have a Tabbar as the primary shell control, and navigate using AppActions (or applinks, for that matter) with a subpage, the tabbar fails to switch to the selected tab.

Steps to Reproduce

  1. Create a new app with a Tabbar as the primary control
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="MauiBug_iOS_AppAction_Navigation_Tabbar.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:MauiBug_iOS_AppAction_Navigation_Tabbar"
    Shell.FlyoutBehavior="Disabled">

    <TabBar>
        <ShellContent
        Title="Page1"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="page1" />
        <ShellContent
        Title="Page2"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="page2" />
        <ShellContent
        Title="Page3"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="page3" />
        <ShellContent
        Title="Page4"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="page4" />
        <ShellContent
        Title="Page5"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="page5" />
    </TabBar>
</Shell>
  1. Create a subpage route meant to be visited below one of those tabpages
    public AppShell()
    {
        InitializeComponent();

        Routing.RegisterRoute("subpage", typeof(MainPage));
    }
  1. Create an app action to navigate to a path like //page1/subpage

         .ConfigureEssentials(essentials =>
            {
                //TODO: it's unclear whether icons must be in the Resources/Images folder or in the Platforms/{platform} folder
                essentials
                    .AddAppAction("page1", "Page 1") //works and changes selected tab
                    .AddAppAction("page2", "Page 2") //works and changes selected tab
                    .AddAppAction("page3/subpage", "Page3/subpage") //does not change active tab (but puts subpage in a nav stack underneath page3 tab)
                    .OnAppAction(App.HandleAppActions);
    
                essentials.UseVersionTracking();
            });
    
    public static void HandleAppActions(AppAction appAction)
    {
        App.Current.Dispatcher.Dispatch(async () =>
        {
            await Shell.Current.GoToAsync($"//{appAction.Id}");
        });
    }
  2. AppActions which only have a top level route like //page will work. AppActions with a subpage route will not change the current tab. Interestingly, if you manually navigate to the tab, you can see the subpage navigation was added, but the selected and visible tab from the tabbar is not shown.

Link to public reproduction project repository

https://github.com/edgiardina/MauiBug_iOS_AppAction_Navigation_Tabbar

Version with bug

7.0.86

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 16.4 but suspect all versions

Did you find any workaround?

No response

Relevant log output

No response

ghost commented 1 year ago

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

Zhanglirong-Winnie commented 8 months ago

Verified this issue with Visual Studio Enterprise 17.9.0 Preview 5. Can repro on iOS platform with sample project. https://github.com/edgiardina/MauiBug_iOS_AppAction_Navigation_Tabbar image

blackforest-tom commented 6 months ago

I found out it has nothing to do with app actions (at least for me). GoToAsync is bugged in iOS for navigating to another Tab's subpage - awaiting it hangs until you switch Tab manually.

Workaround (not sure why it even works, but I tried it out of desperation and it actually does... There has to be some important synchronous code executing within GoToAsync):

        var x = Shell.Current.GoToAsync("//main/tab3/subpage", navigationParameter);
#if IOS
        Shell.Current.CurrentItem.CurrentItem = Shell.Current.CurrentItem.Items[2];
#endif
        await x;

where main is the Route name of the TabBar.

If you change the active tab (setting CurrentItem) before calling GoToAsync, you first see //main/tab3 and from there subpage being pushed upon. If you do it like in the snippet above, it navigates to the subpage directly, without showing tab3 in between.

albyrock87 commented 4 months ago

Additional (simpler) information and a (simpler) how to reproduce repository:

Description

On iOS, using TabBar and navigating to a new Tab also pushing a page onto the navigation stack does not work:

var shell = Shell.Current;
try
{
    // "main" is the `TabBar`
    // "Foo" is a different `ShellContent`
    // "Bar" is a page registered in the `Routing`
    await shell.GoToAsync("//main/Foo/Bar");
}
catch (Exception ex)
{ 
    // Add breakpoint here => not hit
    Console.WriteLine(ex.Message);
}
finally
{
    // Add breakpoint here => not hit
    Console.WriteLine("Finally");
}

Link to public reproduction project repository

https://github.com/albyrock87/maui-shell-issues/blob/main/MainPage.xaml.cs#L14-L28

Version with bug

8.0.40 SR5