the49ltd / The49.Maui.BottomSheet

.NET MAUI library used to display pages as Bottom Sheets
MIT License
314 stars 30 forks source link

bottomsheet behind tabbar #115

Closed takennnusernames closed 1 week ago

takennnusernames commented 3 months ago

is there a way to put the bottom sheet behind the shell.tabbar? i am try to make it as isCancelable=false but still show the tabbar

vhugogarcia commented 1 month ago

Could you please share a sample repository on GitHub showing the issue?

peruchali commented 1 month ago

Could you please share a sample repository on GitHub showing the issue?

@vhugogarcia You can add Shell.TabBarIsVisible="True" to AppShell.xaml's Shell element in the sample project to repro (the TabBar shows up at the bottom). The bottom sheet always shows in front of the tab bar (obscuring it) rather than vertically above it (tested on Android). It feels like there should be an option to show the bottom sheet either vertically above the tab bar (desired behavior of this issue) or covering it entirely (current behavior).

peruchali commented 1 week ago

Here's what worked for me:

  class TabBarPositionCallback : BottomSheetBehavior.BottomSheetCallback
  {
      private readonly BottomSheet m_bottomSheet;

      public TabBarPositionCallback(BottomSheet bottomSheet)
      {
          m_bottomSheet = bottomSheet;
      }

      public override void OnSlide(Android.Views.View bottomSheet, float newState) =>
          SetMarginFromTabBar(bottomSheet);

      public override void OnStateChanged(Android.Views.View bottomSheet, int p1) =>
          SetMarginFromTabBar(bottomSheet);

      private void SetMarginFromTabBar(Android.Views.View bottomSheet)
      {
          if (bottomSheet.Parent is ViewGroup viewGroup)
          {
              // Show above navigation bar and tab bars rather than in front on them.
              Android.Views.Window window = ((AppCompatActivity)m_bottomSheet.Handler.MauiContext.Context).Window;
              Android.Views.View rootView = window.DecorView;

              WindowInsetsCompat windowInsets = ViewCompat.GetRootWindowInsets(rootView);
              AndroidX.Core.Graphics.Insets navigationBarsInset = windowInsets.GetInsetsIgnoringVisibility(WindowInsetsCompat.Type.NavigationBars());
              int bottomMargin = navigationBarsInset.Bottom;

              if (rootView is ViewGroup rootViewGroup &&
                  rootViewGroup.GetFirstChildOfType<BottomNavigationView>() is BottomNavigationView bottomNavigationView)
              {
                  bottomMargin += bottomNavigationView.Height;
              }

              ViewGroup.MarginLayoutParams layoutParameters = viewGroup.LayoutParameters as ViewGroup.MarginLayoutParams;
              layoutParameters.BottomMargin = bottomMargin;
          }
      }
  }

and add this callback with:

void OpenCustomizeBehavior()
{
    var page = new SimplePage();
    page.HasBackdrop = false;

    var callback = new TabBarPositionCallback(page);

    page.Showing += (s, e) =>
    {
        page.Controller.Behavior.AddBottomSheetCallback(callback);
        page.Controller.Behavior.DisableShapeAnimations();
    };
    page.ShowAsync(Window);
}

If HasBackdrop is false, this will show the bottomsheet above the tab/navigation bars.

takennnusernames commented 1 week ago

hello, thanks for sharing @peruchali. i had already created a way around this issue. since the tabbar is always above the bottomsheet, when it is dismissed, it cannot be shown again because the tabbar is blocking the bottomsheet handler, so i created a button that would only show once the bottomsheet is dismissed, this button then activates the bottomsheet again once it is tapped. it would be very nice to have a future function that would place the bottomsheet handler above the tabbar.

peruchali commented 5 days ago

@takennnusernames You can check out #133