Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions samples/CommunityToolkit.Maui.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)
services.AddTransientPopup<TransparentPopup>();
services.AddTransientPopup<UpdatingPopup, UpdatingPopupViewModel>();
services.AddTransientPopup<XamlBindingPopup, XamlBindingPopupViewModel>();
services.AddTransientPopup<SoftInputKeyboardPopup>();
}

static void RegisterEssentials(in IServiceCollection services)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ScrollView>
<VerticalStackLayout Spacing="12">
<Button Text="Simple Popup" Clicked="HandleSimplePopupButtonClicked" />

<Button Text="Self Closing Popup" Clicked="HandleSelfClosingPopupButtonClicked"/>

<Button Text="Button Popup" Clicked="HandleButtonPopupButtonClicked" />
Expand All @@ -35,7 +35,7 @@
<Button Text="Updating Popup" Command="{Binding UpdatingPopupCommand}" />

<Button Text="Show Popup content" Command="{Binding ShowPopupContentCommand}" />

<Button Text="Show Popup in a Modal Page in a Custom Navigation Page" Clicked="HandleModalPopupInCustomNavigationPage" />

<Button Text="Custom Positioning Popup" Clicked="HandlePopupPositionButtonClicked" />
Expand All @@ -49,11 +49,13 @@
<Button Text="Popup Style Page" Clicked="HandleStylePopupButtonClicked" />

<Button Text="OnDisappearing Popup" Clicked="HandleOnDisappearingPopupClicked" />

<Button Text="Complex Popup" Clicked="HandleComplexPopupClicked" />

<Button Text="Collection View Popup" Clicked="HandleCollectionViewPopupClicked" />


<Button Text="Software Input Keyboard Popup" Clicked="HandleSoftInputKeyboardPopupClicked" />

</VerticalStackLayout>
</ScrollView>
</ContentPage.Content>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,9 @@ async void HandleModalPopupInCustomNavigationPage(object? sender, EventArgs even
var customNavigationPage = new NavigationPage(modalPopupPage);
await Shell.Current.Navigation.PushModalAsync(customNavigationPage, true);
}

async void HandleSoftInputKeyboardPopupClicked(object? sender, EventArgs eventArgs)
{
await popupService.ShowPopupAsync<SoftInputKeyboardPopup>(Navigation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8" ?>
<mct:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="CommunityToolkit.Maui.Sample.Views.Popups.SoftInputKeyboardPopup"
CanBeDismissedByTappingOutsideOfPopup="True">

<VerticalStackLayout Spacing="12">

<Label
Text="Keyboard for Entry"
FontSize="18"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Bold" />

<Entry
Placeholder="Click here to enter text..."
TextColor="Black"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center" />

<Label
x:Name="PickerForIOSLabel"
Text="Keyboard for Picker (iOS only)"
FontSize="18"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Bold"
IsVisible="False" />

<Picker
x:Name="PickerForIOS"
Title="Select a monkey"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center"
IsVisible="False">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>

<Label
x:Name="DatePickerForIOSLabel"
Text="Keyboard for DatePicker (iOS only)"
FontSize="18"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Bold"
IsVisible="False" />

<DatePicker
x:Name="DatePickerForIOS"
MinimumDate="01/01/2020"
MaximumDate="12/31/2030"
Date="02/23/2026"
VerticalOptions="Center"
HorizontalOptions="Center"
IsVisible="False" />

<Button
Text="Close"
HorizontalOptions="Center"
VerticalOptions="Center"
Clicked="ClosePopup" />

</VerticalStackLayout>
</mct:Popup>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using CommunityToolkit.Maui.Views;

namespace CommunityToolkit.Maui.Sample.Views.Popups;

public partial class SoftInputKeyboardPopup : Popup
{
public SoftInputKeyboardPopup()
{
InitializeComponent();

#if IOS
PickerForIOSLabel.IsVisible = true;
PickerForIOS.IsVisible = true;
DatePickerForIOSLabel.IsVisible = true;
DatePickerForIOS.IsVisible = true;
#endif
}

async void ClosePopup(object? sender, EventArgs eventArgs)
{
await CloseAsync();
}
}
16 changes: 16 additions & 0 deletions src/CommunityToolkit.Maui/Views/Popup/Popup.android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;

namespace CommunityToolkit.Maui.Views;

public partial class Popup
{
partial void OnPlatformPopupOpened()
{
Microsoft.Maui.Controls.Application.Current?.On<Microsoft.Maui.Controls.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
}

partial void OnPlatformPopupClosed()
{
Microsoft.Maui.Controls.Application.Current?.On<Microsoft.Maui.Controls.PlatformConfiguration.Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Unspecified);
}
}
79 changes: 79 additions & 0 deletions src/CommunityToolkit.Maui/Views/Popup/Popup.ios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Foundation;
using UIKit;

namespace CommunityToolkit.Maui.Views;

public partial class Popup
{
/// <summary>
/// Stores the keyboard will show notification observer to manage keyboard lifecycle.
/// </summary>
NSObject? willShow;

/// <summary>
/// Stores the keyboard will hide notification observer to manage keyboard lifecycle.
/// </summary>
NSObject? willHide;

/// <summary>
/// Stores the native platform view to adjust safe area insets when keyboard appears.
/// </summary>
UIView? popupNativeView;

/// <summary>
/// Stores the view controller associated with the popup to adjust safe area insets.
/// </summary>
UIViewController? viewController;

partial void OnPlatformPopupOpened()
{
if (Handler?.PlatformView is UIView view)
{
popupNativeView = view;
}

willShow = UIKeyboard.Notifications.ObserveWillShow((_, args) => HandleKeyboard(args));

willHide = UIKeyboard.Notifications.ObserveWillHide((_, args) => ResetSafeArea());
}

partial void OnPlatformPopupClosed()
{
willShow?.Dispose();
willHide?.Dispose();

willShow = willHide = null;

popupNativeView = null;
viewController = null;
}

/// <summary>
/// Adjusts the safe area insets when the keyboard appears on iOS.
/// </summary>
/// <param name="args">The keyboard event arguments containing the keyboard frame.</param>
void HandleKeyboard(UIKeyboardEventArgs args)
{
if (popupNativeView is null)
{
return;
}

viewController ??= popupNativeView.Window?.RootViewController?.PresentedViewController;

if (viewController is null)
{
return;
Comment thread
FabriBertani marked this conversation as resolved.
}

viewController.AdditionalSafeAreaInsets = new UIEdgeInsets(0, 0, args.FrameEnd.Height, 0);
}

/// <summary>
/// Resets the safe area insets when the keyboard is hidden on iOS.
/// </summary>
void ResetSafeArea()
{
viewController?.AdditionalSafeAreaInsets = UIEdgeInsets.Zero;
}
}
10 changes: 9 additions & 1 deletion src/CommunityToolkit.Maui/Views/Popup/Popup.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public Popup()
/// </remarks>
[BindableProperty]
public partial bool CanBeDismissedByTappingOutsideOfPopup { get; set; }

/// <summary>
/// Gets or sets the padding between the <see cref="Popup"/> border and the <see cref="Popup"/> content.
/// </summary>
Expand All @@ -74,11 +74,15 @@ public Popup()
internal void NotifyPopupIsOpened()
{
Opened?.Invoke(this, EventArgs.Empty);

OnPlatformPopupOpened();
}

internal void NotifyPopupIsClosed()
{
Closed?.Invoke(this, EventArgs.Empty);

OnPlatformPopupClosed();
}

private protected PopupPage GetPopupPage()
Expand All @@ -97,6 +101,10 @@ private protected PopupPage GetPopupPage()

throw new PopupNotFoundException();
}

partial void OnPlatformPopupOpened();

partial void OnPlatformPopupClosed();
}

/// <summary>
Expand Down
6 changes: 4 additions & 2 deletions src/CommunityToolkit.Maui/Views/Popup/PopupPage.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public PopupPage(Popup popup, IPopupOptions? popupOptions)
Shell.SetPresentationMode(this, PresentationMode.ModalNotAnimated);
On<iOS>().SetModalPresentationStyle(UIModalPresentationStyle.OverFullScreen);
NavigationPage.SetHasNavigationBar(this, false);

this.SafeAreaEdges = new SafeAreaEdges(SafeAreaRegions.Container, SafeAreaRegions.Container, SafeAreaRegions.Container, SafeAreaRegions.SoftInput);
}

public event EventHandler<IPopupResult>? PopupClosed;
Expand Down Expand Up @@ -221,7 +223,7 @@ public PopupPageLayout(in Popup popupContent, in IPopupOptions options, in Actio
Content = popupContent
};

// Bind `Popup` values through to Border using OneWay Bindings
// Bind `Popup` values through to Border using OneWay Bindings
PopupBorder.SetBinding(Border.MarginProperty, static (Popup popup) => popup.Margin, source: popupContent, mode: BindingMode.OneWay, converter: new MarginConverter());
PopupBorder.SetBinding(Border.BackgroundProperty, static (Popup popup) => popup.Background, source: popupContent, mode: BindingMode.OneWay);
PopupBorder.SetBinding(Border.BackgroundColorProperty, static (Popup popup) => popup.BackgroundColor, source: popupContent, mode: BindingMode.OneWay, converter: new BackgroundColorConverter());
Expand Down Expand Up @@ -254,7 +256,7 @@ void HandleOverlayTapped(object? sender, TappedEventArgs e)
return;
}

// Execute tapOutsideOfPopupCommand only if tap occurred outside the PopupBorder
// Execute tapOutsideOfPopupCommand only if tap occurred outside the PopupBorder
if (PopupBorder.Bounds.Contains(position.Value) is false)
{
tryExecuteTapOutsideOfPopupCommand();
Expand Down
Loading