2

I put a lot of effort into research, but I can't not solve my issue.

What I want to achieve:

I would like to use Xamarin Shell Navigation and hide the Top Navigation Tabs (not title bar --> called "navbar", not "tabbar"). Watch out for the image and the orange marked section.

Shell.TabBarIsVisible="False" hides Bottom "TabBar" ("Tab 1", "Tab 2", "Tab 3")
Shell.NavBarIsVisible="False" hides Title Bar ("Page 1 Full Title")

Nothing hides the Top Navigation Tabs below that Title Bar



That is my structure:

 <Shell>
    <TabBar x:Name="RootTab">
        <Tab 
            Title="Tab1" >
            <ShellContent 
                Route="page1" 
                Title="page1" 
                ContentTemplate="{DataTemplate view:Page1}" />
            <ShellContent 
                Route="page2" 
                Title="page2" 
                ContentTemplate="{DataTemplate view:Page2}" />
            <ShellContent 
                Route="page3" 
                Title="page3" 
                ContentTemplate="{DataTemplate view:Page3}" />
            <ShellContent 
                Route="page4" 
                Title="page4" 
                ContentTemplate="{DataTemplate view:Page4}" />
        </Tab>
        <Tab 
            Title="Tab2" >
            <ShellContent 
                Route="tab2" 
                Title="tab2" 
                ContentTemplate="{DataTemplate view:Tab2Page}" />
        </Tab>
        <Tab 
            Title="Tab3" >
            <ShellContent 
                Route="tab3" 
                Title="tab3" 
                ContentTemplate="{DataTemplate view:Tab3Page}" />
        </Tab>
    </TabBar>
  </Shell>

What i tried?

  • IsTabStop

  • Just placing 1 starting ShellContent (Page 1) in Tab 1 and then manually adding/removing pages (2, 3, 4) via code. That works fine for android. But iOS is showing just a black page after adding the new page and removing the old page from Tab 1.

  • Placing ShellContents outside of TabBar. But then I loose my TabBar...

Shell Image: https://i.stack.imgur.com/WYugb.png

UPDATE:

This works in Android but not in iOS (black page):
Having only one ShellContent in XAML and adding other manually in Code
AppShell.mytab.Items.Add(shell1);
AppShell.mytab.Items.Remove(shell0);

When I add the this line in the middle:
Shell.Current.CurrentItem.Items[0].CurrentItem = shell1; (Items[0] means first tab of TabBar --> "Tab 1")

It looks like it works, hurray! and showing the next page but it produces an error: System.NullReferenceException: 'Object reference not set to an instance of an object' ShellSectionRootRenderer.cs:201

Seems like https://github.com/xamarin/Xamarin.Forms/issues/5428
and https://github.com/xamarin/Xamarin.Forms/pull/10500

Other thread missing IsVisible option https://github.com/xamarin/Xamarin.Forms/issues/5232

IsVisible was planned but removed because of naming issues https://github.com/xamarin/Xamarin.Forms/pull/9023



UPDATE 2!

TODAYs Update/Release from Xamarin.Forms 4.5.0.657 to 4.6.0.726 solved the issue. Adding and removing is no working fine in iOS!

https://github.com/xamarin/Xamarin.Forms/pull/10500
Xamarin.Forms 4.6 Branch: Latest commit 18 hours ago

Malte
  • 51
  • 1
  • 10
  • If you hide the top tabs , how you switch(navigate) between the ShellContents ? – ColeX Apr 29 '20 at 09:31
  • await Shell.Current.GoToAsync("///" + routeValue); @ColeXia-MSFT With that comment you can switch between the pages. This works also if you move the ShellContent Items outside the TabBar. But then on these pages there is no TabBar for sure. – Malte Apr 29 '20 at 10:06
  • I know you can go to the page via route pattern in code , but how do you trigger it ? (without press tabs) – ColeX Apr 29 '20 at 10:33
  • @ColeXia-MSFT I have my own "wizard" (1-2-3-4) where I trigger page switches. And in the OnBackButton Method. Also I have a few "Next" Buttons on the pages itself where I trigger page switch. I build a central handler for it in the AppShell.xaml.cs where I do some validation. – Malte Apr 29 '20 at 11:08
  • The top tabs can't be hidden in Shell project , and i think you don't need warp the fours pages into tab (just remain the first page) , you can instantiate them in code behind, switch between them via route pattern . – ColeX Apr 29 '20 at 11:17
  • Yes, this is a problem. Yes, I know that instantiating in the code behind works. But actually only for Android. On iOS I get a black page. Did you get it working for both? – Malte Apr 29 '20 at 11:39

2 Answers2

0

You could remain only first contentpage inside Tab in AppShell .

<TabBar x:Name="RootTab">
    <Tab  Title="Tab1">
        <ShellContent 
            Route="page1" 
            Title="page1" 
            ContentTemplate="{DataTemplate view:Page1}" />
    </Tab>
    <Tab 
        Title="Tab2" >
        <ShellContent 
            Route="tab2" 
            Title="tab2" 
            ContentTemplate="{DataTemplate view:Tab2Page}" />
    </Tab>
    <Tab 
        Title="Tab3" >
        <ShellContent 
            Route="tab3" 
            Title="tab3" 
            ContentTemplate="{DataTemplate view:Tab3Page}" />
    </Tab>
</TabBar>

And navigate between pages using old ways

// your "wizard"
await Navigation.PushAsync(new Page2());

Update

If you want hide the back button , add a transparent image into project ,and set in xaml

<Shell.BackButtonBehavior>
    <BackButtonBehavior IconOverride="transparent.png" IsEnabled="False"/>
</Shell.BackButtonBehavior>
ColeX
  • 14,062
  • 5
  • 43
  • 240
  • Thank you that works, except that I now get display a "backitem" in the title bar. How to prevent this? And navigating back produces a "page must not have a parent". – Malte Apr 29 '20 at 13:56
  • Hi, thank you very much for the hiding option. I just have to figure out the whole navigation stack because it fails when navigating back. I could be so easy if shell would have a Shell.TopTabsVisible = False option... then there would be no need to mix shell navigation with the old navigation. I just don't get it why add/remove items from tab works for android but not for ios. Isn't it a bug? – Malte Apr 29 '20 at 15:04
  • Maybe I have to create a sample project. But cleaning would take too long today. I will post another progress in that topic in the question because it is too long for comment. – Malte Apr 29 '20 at 15:41
  • It was a bug in Xamarin.Forms. After todays release 4.6 my code worked for both android **and iOS** without any code change. Thank you very much anyway! – Malte Apr 29 '20 at 16:31
  • If problem solved , could you post your solution and mark it as answer ? – ColeX May 04 '20 at 00:57
0

Upgrading to Xamarin 4.6 fixed the bug / problem.

Here is my code / solution.

AppShell.xaml

<TabBar Route="tabBar">
        <Tab 
            x:Name="myTab" 
            Route="tab1"
            Icon="tab_icon1.png">
            <ShellContent 
                x:Name="shellStart"
                Route="route1A" 
                Title="title" 
                ContentTemplate="{DataTemplate view:Page1A}" />
        </Tab>
        <Tab 
            Route="tab2"
            Icon="tab_icon2.png">
            <ShellContent 
                Route="route2" 
                Title="title2" 
                ContentTemplate="{DataTemplate view:Page2}" />
        </Tab>
        </Tab>
        <Tab 
            Route="tab3"
            Icon="tab_icon3.png">
            <ShellContent 
                Route="route3" 
                Title="title3" 
                ContentTemplate="{DataTemplate view:Page3}" />
        </Tab>
    </TabBar>

AppShell.xaml.cs

public ShellContent shell0;
public ShellContent shell1;
public ShellContent shell2;
public ShellContent shell3;
public static Tab tabLocal;

constructor

            tabLocal = myTab;
            shell0 = shellStart;
            shell1 = new ShellContent()
            {
                Content = new Page1B(),
                Title = "",
                Route = ""
            };
            shell2 = .... Page1C() ...
            shell3 = .... Page1D() ...
            ...

Switching page 0 to 1

AppShell.tabLocal.Items.Add(shell1);
AppShell.tabLocal.Items.Remove(shell0);

Maybe these two method for handling the navigation is useful

protected async override void OnNavigating(ShellNavigatingEventArgs args)
protected override void OnNavigated(ShellNavigatedEventArgs args)
Malte
  • 51
  • 1
  • 10