Skip to content

Commit

Permalink
Fix Popup size on Android and iOS (#1361)
Browse files Browse the repository at this point in the history
* Fix Popup size on Android

* Fix Popup size on Android

* Fix Popup size on Android

* Fix Popup size on Android and iOS

* Invert if

* Change local variable to static variable

* Fix popup position and closing

* Use pattern matching

* Change rootViewController

* Add CustomSizeAndPositionPopupPage

* Update CustomSizeAndPositionPopupPage.xaml

* Update CustomSizeAndPositionPopupPage.xaml

* Fixed MacCatalyst Popup position

* Fixed MacCatalyst Popup size

* Fix MacCatalyst Popup margin

* Fix Android popup size

* Update Formatting

---------

Co-authored-by: Brandon Minnick <[email protected]>
  • Loading branch information
cat0363 and brminnick authored Sep 29, 2023
1 parent 7dd409e commit d2ee835
Show file tree
Hide file tree
Showing 11 changed files with 461 additions and 98 deletions.
1 change: 1 addition & 0 deletions samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public partial class AppShell : Shell
CreateViewModelMapping<LazyViewPage, LazyViewViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
CreateViewModelMapping<MediaElementPage, MediaElementViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),

CreateViewModelMapping<CustomSizeAndPositionPopupPage, CustomSizeAndPositionPopupViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
CreateViewModelMapping<MultiplePopupPage, MultiplePopupViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
CreateViewModelMapping<PopupAnchorPage, PopupAnchorViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
CreateViewModelMapping<PopupLayoutAlignmentPage, PopupLayoutAlignmentViewModel, ViewsGalleryPage, ViewsGalleryViewModel>(),
Expand Down
1 change: 1 addition & 0 deletions samples/CommunityToolkit.Maui.Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static void RegisterViewsAndViewModels(in IServiceCollection services)
services.AddTransientWithShellRoute<LazyViewPage, LazyViewViewModel>();
services.AddTransientWithShellRoute<MediaElementPage, MediaElementViewModel>();

services.AddTransientWithShellRoute<CustomSizeAndPositionPopupPage, CustomSizeAndPositionPopupViewModel>();
services.AddTransientWithShellRoute<MultiplePopupPage, MultiplePopupViewModel>();
services.AddTransientWithShellRoute<PopupAnchorPage, PopupAnchorViewModel>();
services.AddTransientWithShellRoute<PopupLayoutAlignmentPage, PopupLayoutAlignmentViewModel>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8"?>

<pages:BasePage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
xmlns:viewModels="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Views"
x:Class="CommunityToolkit.Maui.Sample.Pages.Views.CustomSizeAndPositionPopupPage"
Title="Custom Popup Size and Position"
x:TypeArguments="viewModels:CustomSizeAndPositionPopupViewModel"
x:DataType="viewModels:CustomSizeAndPositionPopupViewModel">

<ContentPage.Resources>
<ControlTemplate x:Key="RadioButtonTemplate">
<Border Stroke="#F3F2F1"
StrokeThickness="2"
StrokeShape="RoundRectangle 10"
BackgroundColor="#F3F2F1"
HeightRequest="90"
WidthRequest="90"
HorizontalOptions="Start"
VerticalOptions="Start">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CheckedStates">
<VisualState x:Name="Checked">
<VisualState.Setters>
<Setter TargetName="check"
Property="Opacity"
Value="1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Unchecked">
<VisualState.Setters>
<Setter TargetName="check"
Property="Opacity"
Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid Margin="4"
WidthRequest="90"
BackgroundColor="Transparent">
<Grid Margin="0,0,4,0"
WidthRequest="18"
HeightRequest="18"
HorizontalOptions="End"
VerticalOptions="Start">
<Ellipse Stroke="Blue"
Fill="White"
WidthRequest="16"
HeightRequest="16"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Ellipse x:Name="check"
Fill="Blue"
WidthRequest="8"
HeightRequest="8"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Grid>
<ContentPresenter />
</Grid>
</Border>
</ControlTemplate>

<Style TargetType="RadioButton">
<Setter Property="ControlTemplate"
Value="{StaticResource RadioButtonTemplate}" />
</Style>
</ContentPage.Resources>

<Grid RowDefinitions="24,100,24,100,24,36,24,36,44"
ColumnDefinitions="*,*,*,*"
RowSpacing="8"
ColumnSpacing="4">

<Label Grid.Row="0"
Grid.ColumnSpan="4"
Text="HorizontalOptions"
VerticalOptions="Center"
FontAttributes="Bold" />

<RadioButton Grid.Row="1"
Grid.Column="0"
IsChecked="{Binding IsStartHorizontalOptionSelected}"
GroupName="HorizontalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Start" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="1"
Grid.Column="1"
IsChecked="{Binding IsCenterHorizontalOptionSelected}"
GroupName="HorizontalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Center" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="1"
Grid.Column="2"
IsChecked="{Binding IsEndHorizontalOptionSelected}"
GroupName="HorizontalRadioButtonGroup">
<RadioButton.Content>
<Label Text="End" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="1"
Grid.Column="3"
IsChecked="{Binding IsFillHorizontalOptionSelected}"
GroupName="HorizontalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Fill" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<Label Text="VerticalOptions"
VerticalOptions="Center"
FontAttributes="Bold"
Grid.Row="2"
Grid.ColumnSpan="4" />

<RadioButton Grid.Row="3"
Grid.Column="0"
IsChecked="{Binding IsStartVerticalOptionSelected}"
GroupName="VerticalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Start" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="3"
Grid.Column="1"
IsChecked="{Binding IsCenterVerticalOptionSelected}"
GroupName="VerticalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Center" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="3"
Grid.Column="2"
IsChecked="{Binding IsEndVerticalOptionSelected}"
GroupName="VerticalRadioButtonGroup">
<RadioButton.Content>
<Label Text="End" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<RadioButton Grid.Row="3"
Grid.Column="3"
IsChecked="{Binding IsFillVerticalOptionSelected}"
GroupName="VerticalRadioButtonGroup">
<RadioButton.Content>
<Label Text="Fill" TextColor="Black" VerticalTextAlignment="Center" Margin="4,0,0,0" />
</RadioButton.Content>
</RadioButton>

<Label Grid.Row="4"
Grid.ColumnSpan="4"
Text="Width"
VerticalOptions="Center"
FontAttributes="Bold" />

<Entry Grid.Row="5"
Grid.Column="0"
Text="{Binding Width}"
Placeholder="100"
Keyboard="Numeric"
HorizontalTextAlignment="End" />

<Label Grid.Row="6"
Grid.ColumnSpan="4"
Text="Height"
VerticalOptions="Center"
FontAttributes="Bold" />

<Entry Grid.Row="7"
Grid.Column="0"
Text="{Binding Height}"
Placeholder="100"
Keyboard="Numeric"
HorizontalTextAlignment="End" />

<Button Grid.Row="8"
Grid.ColumnSpan="4"
Text="Show"
TextColor="White"
HorizontalOptions="Center"
Command="{Binding ExecuteShowButtonCommand, Mode=OneTime}" />
</Grid>
</pages:BasePage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using CommunityToolkit.Maui.Sample.ViewModels.Views;

namespace CommunityToolkit.Maui.Sample.Pages.Views;

public partial class CustomSizeAndPositionPopupPage : BasePage<CustomSizeAndPositionPopupViewModel>
{
public CustomSizeAndPositionPopupPage(CustomSizeAndPositionPopupViewModel viewModel) : base(viewModel)
{
InitializeComponent();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@
</ContentPage.Resources>

<ScrollView>
<Grid ColumnDefinitions="Auto, Auto, Auto"
<Grid ColumnDefinitions="*,*,*"
HorizontalOptions="Center"
RowDefinitions="Auto, Auto, Auto, Auto"
RowDefinitions="*,*,*,*"
VerticalOptions="Center">

<Label Grid.Row="0"
Grid.ColumnSpan="3"
Style="{StaticResource Header}"
Text="Popup's can be positioned anywhere on the screen using VerticalOptions and HorizontalOptions. Tap the arrows below to see how this works." />
Text="Popup's can be positioned anywhere on the screen using VerticalOptions and HorizontalOptions. Tap the arrows below to see how this works."
HorizontalTextAlignment="Center"/>

<Button Grid.Row="1"
Grid.Column="0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using CommunityToolkit.Maui.Sample.Views.Popups;
using CommunityToolkit.Maui.Views;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace CommunityToolkit.Maui.Sample.ViewModels.Views;

public partial class CustomSizeAndPositionPopupViewModel : BaseViewModel
{
[ObservableProperty, NotifyCanExecuteChangedFor(nameof(ExecuteShowButtonCommand))]
double height = 100, width = 100;

[ObservableProperty, NotifyCanExecuteChangedFor(nameof(ExecuteShowButtonCommand))]
bool isStartHorizontalOptionSelected = true, isCenterHorizontalOptionSelected, isEndHorizontalOptionSelected, isFillHorizontalOptionSelected,
isStartVerticalOptionSelected = true, isCenterVerticalOptionSelected, isEndVerticalOptionSelected, isFillVerticalOptionSelected;

[RelayCommand(CanExecute = nameof(CanShowButtonExecute))]
public Task ExecuteShowButton()
{
Microsoft.Maui.Primitives.LayoutAlignment? verticalOptions = null, horizontalOptions = null;

if (IsStartVerticalOptionSelected)
{
verticalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Start;
}
if (IsCenterVerticalOptionSelected)
{
verticalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Center;
}
if (IsEndVerticalOptionSelected)
{
verticalOptions = Microsoft.Maui.Primitives.LayoutAlignment.End;
}
if (IsFillVerticalOptionSelected)
{
verticalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Fill;
}

ArgumentNullException.ThrowIfNull(verticalOptions);

if (IsStartHorizontalOptionSelected)
{
horizontalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Start;
}
if (IsCenterHorizontalOptionSelected)
{
horizontalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Center;
}
if (IsEndHorizontalOptionSelected)
{
horizontalOptions = Microsoft.Maui.Primitives.LayoutAlignment.End;
}
if (IsFillHorizontalOptionSelected)
{
horizontalOptions = Microsoft.Maui.Primitives.LayoutAlignment.Fill;
}

ArgumentNullException.ThrowIfNull(horizontalOptions);

var popup = new RedBlueBoxPopup
{
Size = new Size(Width, Height),
VerticalOptions = verticalOptions.Value,
HorizontalOptions = horizontalOptions.Value
};

return Shell.Current.ShowPopupAsync(popup);
}

// Ensure at least one Horizontal Option is selected, one Vertical Option is selected, Height > 0, and Width > 0
bool CanShowButtonExecute() => (IsStartHorizontalOptionSelected || IsCenterHorizontalOptionSelected || IsEndHorizontalOptionSelected || IsFillHorizontalOptionSelected)
&& (IsStartVerticalOptionSelected || IsCenterVerticalOptionSelected || IsEndVerticalOptionSelected || IsFillVerticalOptionSelected)
&& Height > 0
&& Width > 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public ViewsGalleryViewModel()
SectionModel.Create<AvatarViewShadowsViewModel>("AvatarView Shadows Page", Colors.Red, "A page demonstrating AvatarViews with various shadow options."),
SectionModel.Create<AvatarViewShapesViewModel>("AvatarView Shapes Page", Colors.Red, "A page demonstrating AvatarViews with various shape options."),
SectionModel.Create<AvatarViewSizesViewModel>("AvatarView Sizes Page", Colors.Red, "A page demonstrating AvatarViews with various size options."),
SectionModel.Create<CustomSizeAndPositionPopupViewModel>("Custom Size and Positioning Popup", Colors.Red, "Displays a basic popup anywhere on the screen with a custom size using VerticalOptions and HorizontalOptions."),
SectionModel.Create<DrawingViewViewModel>("DrawingView", Colors.Red, "DrawingView provides a canvas for users to \"paint\" on the screen. The drawing can also be captured and displayed as an Image."),
SectionModel.Create<ExpanderViewModel>("Expander Page", Colors.Red, "Expander allows collapse and expand content."),
SectionModel.Create<BasicMapsViewModel>("Windows Maps Basic Page", Colors.Red, "A page demonstrating a basic example of .NET MAUI Maps for Windows."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public partial class PopupHandler : ElementHandler<IPopup, MauiPopup>
/// <param name="result">The result that should return from this Popup.</param>
public static async void MapOnClosed(PopupHandler handler, IPopup view, object? result)
{
var vc = handler.PlatformView.ViewController;
if (vc is not null)
var presentationController = handler.PlatformView.PresentationController;
if (presentationController?.PresentedViewController is UIViewController presentationViewController)
{
await vc.DismissViewControllerAsync(true);
await presentationViewController.DismissViewControllerAsync(true);
}

view.HandlerCompleteTCS.TrySetResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,13 @@ public void SetElement(IPopup element)
_ = View ?? throw new InvalidOperationException($"{nameof(View)} cannot be null.");
_ = VirtualView ?? throw new InvalidOperationException($"{nameof(VirtualView)} cannot be null.");

#if MACCATALYST
var pagehandler = VirtualView.Parent.Handler as PageHandler;
var rootViewController = pagehandler?.ViewController ?? WindowStateManager.Default.GetCurrentUIViewController() ?? throw new InvalidOperationException($"{nameof(PageHandler.ViewController)} cannot be null.");
#else
var rootViewController = WindowStateManager.Default.GetCurrentUIViewController() ?? throw new InvalidOperationException($"{nameof(PageHandler.ViewController)} cannot be null.");
#endif

ViewController ??= rootViewController;
SetDimmingBackgroundEffect();
}
Expand Down
Loading

0 comments on commit d2ee835

Please sign in to comment.