Skip to content

Commit 05be19c

Browse files
authored
Merge branch 'main' into FullScreenEvents
2 parents 4867fa6 + be32188 commit 05be19c

File tree

8 files changed

+126
-83
lines changed

8 files changed

+126
-83
lines changed

samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
<pages:BasePage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
33
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
44
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
5+
xmlns:alertPages="clr-namespace:CommunityToolkit.Maui.Sample.Pages.Alerts"
56
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
6-
x:Class="CommunityToolkit.Maui.Sample.Pages.Alerts.SnackbarPage"
77
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Alerts"
8+
x:Class="CommunityToolkit.Maui.Sample.Pages.Alerts.SnackbarPage"
89
x:TypeArguments="vm:SnackbarViewModel"
910
x:DataType="vm:SnackbarViewModel">
1011

@@ -14,26 +15,34 @@
1415
</ResourceDictionary>
1516
</pages:BasePage.Resources>
1617

17-
<VerticalStackLayout Spacing="12">
18-
19-
<Label Text="The Snackbar is a timed alert that appears at the bottom of the screen by default. It is dismissed after a configurable duration of time. Snackbar is fully customizable and can be anchored to any IView."
20-
LineBreakMode = "WordWrap" />
18+
<Grid RowSpacing="12"
19+
RowDefinitions="70,20,40,40,40,20">
20+
<Label Grid.Row="0"
21+
Text="The Snackbar is a timed alert that appears at the bottom of the screen by default. It is dismissed after a configurable duration of time. Snackbar is fully customizable and can be anchored to any IView."
22+
HorizontalTextAlignment="Justify"
23+
LineBreakMode = "WordWrap" />
2124

22-
<Label Text="Windows uses toast notifications to display snackbar. Make sure you switched off Focus Assist."
25+
<Label Grid.Row="1"
26+
Text="NOTE: Windows uses toast notifications to display snackbar. Be sure you've switched off Focus Assist."
2327
IsVisible="{OnPlatform Default='false', WinUI='true'}"/>
2428

25-
<Button Clicked="DisplayDefaultSnackbarButtonClicked"
26-
Text="Display Default Snackbar"/>
29+
<Button Grid.Row="2"
30+
Clicked="DisplayDefaultSnackbarButtonClicked"
31+
Text = "Display Default Snackbar"/>
2732

28-
<Button x:Name="DisplayCustomSnackbarButton"
29-
Clicked="DisplayCustomSnackbarButtonClicked"
30-
TextColor="{Binding Source={RelativeSource Self}, Path=BackgroundColor, Converter={StaticResource ColorToColorForTextConverter}, x:DataType=Button}"/>
33+
<Button Grid.Row="3"
34+
x:Name="DisplayCustomSnackbarButtonAnchoredToButton"
35+
Clicked="DisplayCustomSnackbarAnchoredToButtonClicked"
36+
Text="{x:Static alertPages:SnackbarPage.DisplayCustomSnackbarText}"
37+
TextColor="{Binding Source={RelativeSource Self}, Path=BackgroundColor, Converter={StaticResource ColorToColorForTextConverter}, x:DataType=Button}"/>
3138

32-
<Button x:Name="DisplaySnackbarInModalButton"
39+
<Button Grid.Row="4"
40+
x:Name="DisplaySnackbarInModalButton"
3341
Text="Show Snackbar in Modal Page"
3442
Clicked="DisplaySnackbarInModalButtonClicked"/>
3543

36-
<Label x:Name="SnackbarShownStatus" />
37-
</VerticalStackLayout>
44+
<Label Grid.Row="5"
45+
x:Name="SnackbarShownStatus" />
46+
</Grid>
3847

3948
</pages:BasePage>

samples/CommunityToolkit.Maui.Sample/Pages/Alerts/SnackbarPage.xaml.cs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,21 @@ namespace CommunityToolkit.Maui.Sample.Pages.Alerts;
1212

1313
public partial class SnackbarPage : BasePage<SnackbarViewModel>
1414
{
15-
const string displayCustomSnackbarText = "Display a Custom Snackbar, Anchored to this Button";
15+
public const string DisplayCustomSnackbarText = "Display Custom Snackbar";
1616
const string dismissCustomSnackbarText = "Dismiss Custom Snackbar";
17-
readonly IReadOnlyList<Color> colors = typeof(Colors)
17+
18+
readonly IReadOnlyList<Color> colors = [.. typeof(Colors)
1819
.GetFields(BindingFlags.Static | BindingFlags.Public)
1920
.ToDictionary(c => c.Name, c => (Color)(c.GetValue(null) ?? throw new InvalidOperationException()))
20-
.Values.ToList();
21+
.Values];
2122

2223
ISnackbar? customSnackbar;
2324

2425
public SnackbarPage(SnackbarViewModel snackbarViewModel) : base(snackbarViewModel)
2526
{
2627
InitializeComponent();
2728

28-
DisplayCustomSnackbarButton.Text = displayCustomSnackbarText;
29+
DisplayCustomSnackbarButtonAnchoredToButton.Text = DisplayCustomSnackbarText;
2930

3031
Snackbar.Shown += Snackbar_Shown;
3132
Snackbar.Dismissed += Snackbar_Dismissed;
@@ -34,9 +35,9 @@ public SnackbarPage(SnackbarViewModel snackbarViewModel) : base(snackbarViewMode
3435
async void DisplayDefaultSnackbarButtonClicked(object? sender, EventArgs args) =>
3536
await this.DisplaySnackbar("This is a Snackbar.\nIt will disappear in 3 seconds.\nOr click OK to dismiss immediately");
3637

37-
async void DisplayCustomSnackbarButtonClicked(object? sender, EventArgs args)
38+
async void DisplayCustomSnackbarAnchoredToButtonClicked(object? sender, EventArgs args)
3839
{
39-
if (DisplayCustomSnackbarButton.Text is displayCustomSnackbarText)
40+
if (DisplayCustomSnackbarButtonAnchoredToButton.Text is DisplayCustomSnackbarText)
4041
{
4142
var options = new SnackbarOptions
4243
{
@@ -52,20 +53,20 @@ async void DisplayCustomSnackbarButtonClicked(object? sender, EventArgs args)
5253
"This is a customized Snackbar",
5354
async () =>
5455
{
55-
await DisplayCustomSnackbarButton.BackgroundColorTo(colors[Random.Shared.Next(colors.Count)], length: 500);
56-
DisplayCustomSnackbarButton.Text = displayCustomSnackbarText;
56+
await DisplayCustomSnackbarButtonAnchoredToButton.BackgroundColorTo(colors[Random.Shared.Next(colors.Count)], length: 500);
57+
DisplayCustomSnackbarButtonAnchoredToButton.Text = DisplayCustomSnackbarText;
5758
},
5859
FontAwesomeIcons.Microsoft,
5960
TimeSpan.FromSeconds(30),
6061
options,
61-
DisplayCustomSnackbarButton);
62+
DisplayCustomSnackbarButtonAnchoredToButton);
6263

6364
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
6465
await customSnackbar.Show(cts.Token);
6566

66-
DisplayCustomSnackbarButton.Text = dismissCustomSnackbarText;
67+
DisplayCustomSnackbarButtonAnchoredToButton.Text = dismissCustomSnackbarText;
6768
}
68-
else if (DisplayCustomSnackbarButton.Text is dismissCustomSnackbarText)
69+
else if (DisplayCustomSnackbarButtonAnchoredToButton.Text is dismissCustomSnackbarText)
6970
{
7071
if (customSnackbar is not null)
7172
{
@@ -75,11 +76,11 @@ async void DisplayCustomSnackbarButtonClicked(object? sender, EventArgs args)
7576
customSnackbar.Dispose();
7677
}
7778

78-
DisplayCustomSnackbarButton.Text = displayCustomSnackbarText;
79+
DisplayCustomSnackbarButtonAnchoredToButton.Text = DisplayCustomSnackbarText;
7980
}
8081
else
8182
{
82-
throw new NotSupportedException($"{nameof(DisplayCustomSnackbarButton)}.{nameof(ITextButton.Text)} Not Recognized");
83+
throw new NotSupportedException($"{nameof(DisplayCustomSnackbarButtonAnchoredToButton)}.{nameof(ITextButton.Text)} Not Recognized");
8384
}
8485
}
8586

@@ -97,6 +98,20 @@ async void DisplaySnackbarInModalButtonClicked(object? sender, EventArgs e)
9798
{
9899
if (Application.Current?.Windows[0].Page is Page mainPage)
99100
{
101+
var button = new Button()
102+
.CenterHorizontal()
103+
.Text("Display Snackbar");
104+
button.Command = new AsyncRelayCommand(token => button.DisplaySnackbar(
105+
"This Snackbar is anchored to the button on the bottom to avoid clipping the Snackbar on the top of the Page.",
106+
() => { },
107+
"Close",
108+
TimeSpan.FromSeconds(5), token: token));
109+
110+
var backButton = new Button()
111+
.CenterHorizontal()
112+
.Text("Back to Snackbar MainPage");
113+
backButton.Command = new AsyncRelayCommand(mainPage.Navigation.PopModalAsync);
114+
100115
await mainPage.Navigation.PushModalAsync(new ContentPage
101116
{
102117
Content = new VerticalStackLayout
@@ -105,19 +120,11 @@ await mainPage.Navigation.PushModalAsync(new ContentPage
105120

106121
Children =
107122
{
108-
new Button { Command = new AsyncRelayCommand(static token => Snackbar.Make("Snackbar in a Modal MainPage").Show(token)) }
109-
.Top().CenterHorizontal()
110-
.Text("Display Snackbar"),
123+
button,
111124

112-
new Label()
113-
.Center().TextCenter()
114-
.Text("This is a Modal MainPage"),
115-
116-
new Button { Command = new AsyncRelayCommand(mainPage.Navigation.PopModalAsync) }
117-
.Bottom().CenterHorizontal()
118-
.Text("Back to Snackbar MainPage")
125+
backButton
119126
}
120-
}.Center()
127+
}
121128
}.Padding(12));
122129
}
123130
}

samples/CommunityToolkit.Maui.Sample/Pages/Base/BasePage.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
using System.Diagnostics;
22
using CommunityToolkit.Maui.Sample.ViewModels;
3+
using Microsoft.Maui.Controls.PlatformConfiguration;
4+
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
35

46
namespace CommunityToolkit.Maui.Sample.Pages;
57

6-
public abstract class BasePage<TViewModel>(TViewModel viewModel) : BasePage(viewModel)
8+
public abstract class BasePage<TViewModel>(TViewModel viewModel, bool shouldUseSafeArea = true) : BasePage(viewModel, shouldUseSafeArea)
79
where TViewModel : BaseViewModel
810
{
911
public new TViewModel BindingContext => (TViewModel)base.BindingContext;
1012
}
1113

1214
public abstract class BasePage : ContentPage
1315
{
14-
protected BasePage(object? viewModel = null)
16+
protected BasePage(object? viewModel = null, bool shouldUseSafeArea = true)
1517
{
1618
BindingContext = viewModel;
1719
Padding = 12;
1820

21+
On<iOS>().SetUseSafeArea(shouldUseSafeArea);
22+
1923
if (string.IsNullOrWhiteSpace(Title))
2024
{
2125
Title = GetType().Name;

src/CommunityToolkit.Maui.Camera/AppBuilderExtensions.shared.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ namespace CommunityToolkit.Maui;
1010
/// </summary>
1111
[SupportedOSPlatform("windows10.0.10240.0")]
1212
[SupportedOSPlatform("android21.0")]
13-
[SupportedOSPlatform("ios")]
14-
[SupportedOSPlatform("maccatalyst")]
15-
[SupportedOSPlatform("tizen")]
13+
[SupportedOSPlatform("ios15.0")]
14+
[SupportedOSPlatform("maccatalyst15.0")]
15+
[SupportedOSPlatform("tizen6.5")]
1616
public static class AppBuilderExtensions
1717
{
1818
/// <summary>

src/CommunityToolkit.Maui.Core/Views/Alert/Alert.macios.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace CommunityToolkit.Maui.Core.Views;
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
namespace CommunityToolkit.Maui.Core.Views;
24

35
/// <summary>
46
/// Popup for iOS + MacCatalyst
@@ -10,9 +12,10 @@ public class Alert
1012
/// <summary>
1113
/// Initialize Alert
1214
/// </summary>
13-
public Alert()
15+
/// <param name="shouldFillAndExpandHorizontally">Should stretch container horizontally to fit the screen</param>
16+
public Alert(bool shouldFillAndExpandHorizontally = false)
1417
{
15-
AlertView = [];
18+
AlertView = new AlertView(shouldFillAndExpandHorizontally);
1619

1720
AlertView.ParentView.AddSubview(AlertView);
1821
AlertView.ParentView.BringSubviewToFront(AlertView);
@@ -48,7 +51,7 @@ public Alert()
4851
/// </summary>
4952
public void Dismiss()
5053
{
51-
if (timer != null)
54+
if (timer is not null)
5255
{
5356
timer.Invalidate();
5457
timer.Dispose();
@@ -62,6 +65,7 @@ public void Dismiss()
6265
/// <summary>
6366
/// Show the <see cref="Alert"/> on the screen
6467
/// </summary>
68+
[MemberNotNull(nameof(timer))]
6569
public void Show()
6670
{
6771
AlertView.AnchorView = Anchor;

0 commit comments

Comments
 (0)