The49.Maui.BottomSheet 1.0.0-alpha5

This is a prerelease version of The49.Maui.BottomSheet.
There is a newer version of this package available.
See the version list below for details.
dotnet add package The49.Maui.BottomSheet --version 1.0.0-alpha5                
NuGet\Install-Package The49.Maui.BottomSheet -Version 1.0.0-alpha5                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="The49.Maui.BottomSheet" Version="1.0.0-alpha5" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add The49.Maui.BottomSheet --version 1.0.0-alpha5                
#r "nuget: The49.Maui.BottomSheet, 1.0.0-alpha5"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install The49.Maui.BottomSheet as a Cake Addin
#addin nuget:?package=The49.Maui.BottomSheet&version=1.0.0-alpha5&prerelease

// Install The49.Maui.BottomSheet as a Cake Tool
#tool nuget:?package=The49.Maui.BottomSheet&version=1.0.0-alpha5&prerelease                

NOTE: Coming from Gerald Versluis' video? Make sure to check the section on what changed since the video was made

What is Maui.BottomSheet?

Setup

Enable this plugin by calling UseBottomSheet() in your MauiProgram.cs

using Maui.Insets;

public static class MauiProgram
{
	public static MauiApp CreateMauiApp()
	{
		var builder = MauiApp.CreateBuilder();
		
		// Initialise the plugin
		builder
                    .UseMauiApp<App>()
                    .UseBottomSheet();

		// the rest of your logic...
	}
}

XAML usage

In order to make use of the plugin within XAML you can use this namespace:

xmlns:the49="https://schemas.the49.com/dotnet/2023/maui"

Quick usage

Simply create a ContentPage. Replace the extended class with BottomSheetPage in code-behind and in XAML:

using The49.Maui.BottomSheet;

public class MySheetPage : BottomSheetPage
{
    public MySheetPage()
    {
        InitializeComponent();
    }
}
<the49:BottomSheet xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:the49="https://schemas.the49.com/dotnet/2023/maui"
             x:Class="MyApp.MySheetPage"
             Title="MySheetPage">
            
</the49:BottomSheet>

The sheet can be opened by calling the Show(Window) method of the page. It can be closed using Dismiss():


const page = new MySheetPage();

// Pass the window in which the sheet should show. Usually accessible from any other page of the app.
page.Show(Window);

// Call to programatically close the sheet
page.Dismiss();

On Android, make sure your application's theme extends the Material3 theme. This mean you need a Platforms/Android/Resources/values/styles.xml file with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<resources>
	<style name="Maui.MainTheme" parent="Theme.Material3.DayNight"></style>
</resources>

If you already have this file, just make sure the Maui.MainTheme style inherits the Theme.Material3.DayNight parent.

API

This library offers a BottomSheetPage, an extension of the ContentPage with extra functionality

Properties

The following properties are available to use:

Name Type Default value Description Android iOS
HasBackdrop bool false Displays the sheet as modal. This has no effect on whether or not the sheet can be dismissed using gestures. ❌*
HasHandle bool false If true, display a drag handle at the top of the sheet
IsCancelable bool true If false, prevents the dismissal of the sheet with user gestures
Detents DetentsCollection new DetentsCollection() { new ContentDetent() }) A collection of detents where the sheet will snap to when dragged. (See the Detents section for more info)

* iOS doesn't support the property largestUndimmedDetentIdentifier for custom detents as of right now. See iOS documentation

Detents:

Detents are snap point at which the sheet will stop when a drag gesture is released See iOS definition.

On Android only 3 detents are supported (See implemenation section for more info).

On iOS, detents are only fully supported for iOS 16 and up. On iOS 15, medium and large detents are used instead See iOS documentation.

Available detents

Name Parameter Description
FullscreenDetent Full height of the screen
ContentDetent Calculates the height of the page's content
AnchorDetent Anchor Anchor expects a View and will set its height to the Y position of that view. This is used to peek some content, then reveal more when the sheet is dragged up
HeightDetent Height Use a dp value to specify the detent height
RatioDetent Ratio Use a ratio of the full screen height

Example:

<the49:BottomSheetPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:the49="https://schemas.the49.com/dotnet/2023/maui"
             x:Class="MyApp.SheetPage"
             Title="SheetPage">
    <the49:BottomSheetPage.Detents>
        <the49:DetentsCollection>
            
            <the49:FullscreenDetent />
            
            <the49:ContentDetent />
            
            <the49:HeightDetent Height="120" />
            
            <the49:RatioDetent Height="0.45" />
            
            <the49:AnchorDetent Anchor="{x:Reference divider}" />
        </the49:DetentsCollection>
    </the49:BottomSheetPage.Detents>
    <VerticalStackLayout Spacing="16">
        <VerticalStackLayout>
            
        </VerticalStackLayout>
        <BoxView x:Name="divider" />
        <VerticalStackLayout>
            
        </VerticalStackLayout>
    </VerticalStackLayout>
</the49:BottomSheetPage>

Custom detent

You can create a custom detent by extending the default Detent class and implementing its GetHeight abstract method

Events

The following events are available to use:

Name EventArg Description Android iOS
Dismissed DismissOrigin Invoked when the sheet is dismissed. The EventArgs will either be DismissOrigin.Gesture when the user dragged it down or DismissOrigin.Programmatic when Dismiss is called.
Showing EventArg.Emtpy Called when the sheet is about to animate in. This is the best time to configure the behavior of the sheet for specific platforms (See Platform specifics)

Platform specifics

On Android, the Google.Android.Material.BottomSheet.BottomSheetBehavior is made available under sheet.Controller.Behavior, to ensure the property is set, access it when the Showing event is fired. Learn more about it here: BottomSheetBehavior  |  Android Developers

On iOS, the UIKit.UISheetPresentationController is made available under sheet.Controller.SheetPresentationController, to ensure the property is set, access it when the Showing event is fired. Learn more about it here: UISheetPresentationController | Apple Developer Documentation

Common questions

How do I prevent the rounded corner to animate on Android?

var sheet = new MySheet();
sheet.Showing += (s, e) =>
{
    page.Controller.Behavior.DisableShapeAnimations();
};
sheet.Show(Window);

How do I change the corner radius?

This will be different on Android and iOS as they each provide their own design implementation

On iOS

var sheet = new MySheet();
sheet.Showing += (s, e) =>
{
    sheet.Controller.SheetPresentationController.PreferredCornerRadius = 2;
};
sheet.Show(Window);

On Android (Using Android styles). In your Platforms/Android/Resources/values/themes.xml (or equivalent) add the following styles

<style name="ThemeOverlay.App.BottomSheetDialog" parent="ThemeOverlay.Material3.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/ModalBottomSheetDialog</item>
</style>

<style name="ModalBottomSheetDialog" parent="Widget.Material3.BottomSheet.Modal">
    <item name="shapeAppearance">@style/ShapeAppearance.App.LargeComponent</item>
</style>

<style name="ShapeAppearance.App.LargeComponent" parent="ShapeAppearance.Material3.LargeComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">2dp</item>
</style>

And in your <style name="Maui.MainTheme" ...> add the following item:

<item name="bottomSheetDialogTheme">@style/ThemeOverlay.App.BottomSheetDialog</item>

Implementation details

iOS

The bottom sheet on iOS is presented using the UIViewController's PresentViewController and configuring the sheet with UISheetPresentationController.

Detents are created using the custom method

Android

The Material library's bottom sheet is used.

Standard sheets attach a CoordinatorLayout to the navigation view and insert a FrameLayout with the com.google.android.material.bottomsheet.BottomSheetBehavior Behavior.

Modal sheets use a BottomSheetDialogFragment

Detents are created using a combination of expandedOffset, halfExpandedRatio and peekHeight. These are the only configurable stop points for the bottom sheets, and that is why this library only supports up to 3 detents on Android.

Changes since Gerald Versluis' video

If you're coming from Gerald Versluis' video, a few things have changed. Here is what you need to know:

  • Property names have been updated to be more consistent, discoverable and aligned with standard MAUI properties:
    • ShowHandle is now HasHandle
    • Cancelable is now IsCancelable
    • IsModal is now HasBackdrop
  • Detents in XAML must be specified within a DetentsCollection

Made within The49

Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  net7.0-android was computed.  net7.0-android33.0 is compatible.  net7.0-ios was computed.  net7.0-ios16.1 is compatible.  net7.0-maccatalyst was computed.  net7.0-maccatalyst16.1 is compatible.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net7.0-windows10.0.19041 is compatible.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.
  • net7.0-android33.0

    • No dependencies.
  • net7.0-ios16.1

    • No dependencies.
  • net7.0-maccatalyst16.1

    • No dependencies.
  • net7.0-windows10.0.19041

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on The49.Maui.BottomSheet:

Repository Stars
securefolderfs-community/SecureFolderFS
Powerful, secure, modern way to keep your files protected.
Version Downloads Last updated
8.0.3 70,995 2/13/2024
8.0.2 14,316 1/16/2024
8.0.1 1,275 1/12/2024
8.0.0 588 1/11/2024
1.0.4 15,673 10/13/2023
1.0.3 2,906 9/20/2023
1.0.2 1,142 9/13/2023
1.0.1 8,327 7/13/2023
1.0.0 990 7/10/2023
1.0.0-rc9 4,573 7/3/2023
1.0.0-rc8 1,100 6/29/2023
1.0.0-rc7 442 6/28/2023
1.0.0-rc6 620 6/27/2023
1.0.0-rc5 767 6/21/2023
1.0.0-rc4 610 6/19/2023
1.0.0-rc3 480 6/16/2023
1.0.0-rc2 2,004 5/26/2023
1.0.0-rc12 397 7/7/2023
1.0.0-rc11 422 7/6/2023
1.0.0-rc10 355 7/6/2023
1.0.0-rc1 782 5/20/2023
1.0.0-alpha7 788 5/9/2023
1.0.0-alpha6 1,957 4/25/2023
1.0.0-alpha5 421 4/24/2023
1.0.0-alpha4 1,033 2/8/2023
1.0.0-alpha3 417 2/8/2023
1.0.0-alpha2 424 2/8/2023
1.0.0-alpha1 461 1/17/2023