PrismLibrary / Prism

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Other
6.35k stars 1.64k forks source link

[Enhancement] Handling double TabbedPage #1944

Closed JeremyBP closed 5 years ago

JeremyBP commented 5 years ago

Summary

In some scenarios, we need to implement a bottom tab bar (with a standard TabbedPage and TabbedPage.ToolbarPlacement="Bottom" for Android) and a top tab bar (i.e. with a Naxam TabbedPage wich is actually a standard TabbedPage on Android and a rendered one on iOS). Using double tabbed pages as explained above renders UI as expected. The first problem I can see is about ViewModel wiring. We should call "ConfigureTabbedPage" from PageNavigationService for both TabbedPage (bottom and top or main and sub). The other one is Navigating from a ContentPage contained in a top tabbed page itself contained in a bottom tabbed page, shows in a modal way, as it can't find a NavigationPage in contentPage.Parent?.Parent (it's a tabbed one in this case).

API Changes

We should look at the third parent to get a NavigationPage and beeing able to navigate as expected.

Changes:

Add

  else if(child is TabbedPage subTabbedPage)
      ConfigureTabbedPage(subTabbedPage, string.Empty);

This will configure the sub TabbedPage with a recursive call (maybe we should allow only one recursive call...)

Replace

  if ((page.Parent is TabbedPage || page.Parent is CarouselPage) && page.Parent?.Parent is NavigationPage navigationParent)

By

  if ((page.Parent is TabbedPage || page.Parent is CarouselPage) && (page.Parent?.Parent is TabbedPage ? page.Parent?.Parent?.Parent : page.Parent?.Parent) is NavigationPage navigationParent)

I was wondering if we'd better handle this one in a more recursive way, I mean looking through parents until finding the first NavigationPage, but who wants to include more than 2 tabs bar in real life?

Intended Use Case

Facebook does it like that:

Image of Facebook double tabs

JeremyBP commented 5 years ago

There's still another thing to think about: deep linking! How to tell Prism to select BottomTabB on BottomTabbedPage and TopTabC on TopTabbedPage (e.g. with Facebook: Group bottom tab and Publications top tab).

I personaly ended with that new method into UriParsingHelper class:

    public static string GetSubSegment(string segment)
    {
        var subSegment = string.Empty;
        if (segment.Count(c => c == '?') > 1)
        {
            var subSegmentIndex = segment.IndexOf('=');
            if (subSegmentIndex > 0)
                subSegment = segment.Substring(subSegmentIndex + 1);
        }

        return subSegment;
    }

called from the ConfigureTabbedPage method in PageNavigationService class:

  else if (child is TabbedPage subTabbedPage)
  {
      var subSegment = UriParsingHelper.GetSubSegment(segment);
      ConfigureTabbedPage(subTabbedPage, subSegment);
  }

and used like so from the navigation uri:

  _navigationService.NavigateAsync("BottomTabbedPage?selectedTab=BottomTabB?selectedTab=TopTabC");

where BottomTabB is a Naxam TopTabbedPage.

I have to admit that getting 2 questionmarks in the same uri may not be a really clean solution. Maybe another symbol to chain tabs selection... But it works so far with first, both or no tab selection.

JeremyBP commented 5 years ago

Well it's not parameters ready, I mean we have to deal with Uri like:

   _navigationService.NavigateAsync("BottomTabbedPage?selectedTab=BottomTabB&param1=4&param2=test?selectedTab=TopTabC&param1=foo");

Keep optimizing :)

brianlagunas commented 5 years ago

I am not sure this is something that is common enough that Prism should try to deal with it. This seems like a highly unique UI pattern that the majority of apps don't use. Essentially, this is an edge case, and in order to support it a number of changes would have to be made with unknown side-effects.

The recommended course of action is to create your own INavigationService and make your modifications to support your specific needs.

JeremyBP commented 5 years ago

Well, I don't know if we could say that Facebook UI (pages) or Twitter UI (notifications) or Instagram UI (user profile) or Pinterest UI (profile) or Eventbrite (tickets) and so on and so on are highly unique and edge cases. But anyway, I understand your side-effects concerns. I'll try to deal with it on my side and share it somewhere if it could help.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.