diff --git a/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml b/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml
index ae76e6e58ba3..0d7e2af9c3b8 100644
--- a/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml
+++ b/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml
@@ -1,14 +1,14 @@
-
+
-
-
-
+ Title="Hide Home Indicator">
+
+
+
+
+
diff --git a/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml.cs b/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml.cs
index e8714bcf249f..12a0730475d8 100644
--- a/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml.cs
+++ b/src/Controls/samples/Controls.Sample/Pages/PlatformSpecifics/iOS/iOSHideHomeIndicatorPage.xaml.cs
@@ -12,9 +12,255 @@ public iOSHideHomeIndicatorPage()
InitializeComponent();
}
- void OnButtonClicked(object sender, EventArgs e)
+ void NavigationPage_Clicked(object sender, EventArgs e)
{
- On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden());
+ Navigation.PushAsync(new iOSHideHomeIndicatorNavigationPageDemo());
+ }
+
+ void TabbedPage_Clicked(object sender, EventArgs e)
+ {
+ Navigation.PushAsync(new iOSHideHomeIndicatorPageDemo());
+ }
+
+ void FlyoutPage_Clicked(object sender, EventArgs e)
+ {
+ Navigation.PushAsync(new iOSHideHomeIndicatorFlyoutPageDemo());
+ }
+
+ void Shell_Clicked(object sender, EventArgs e)
+ {
+ Navigation.PushAsync(new iOSHideHomeIndicatorShellDemo());
+ }
+ }
+
+ public class iOSHideHomeIndicatorNavigationPageDemo : ContentPage
+ {
+ public iOSHideHomeIndicatorNavigationPageDemo()
+ {
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children = {
+ new Button()
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ },
+ new Button()
+ {
+ Text = "Navigate back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ };
+ }
+ }
+
+ public class iOSHideHomeIndicatorFlyoutPageDemo : Microsoft.Maui.Controls.FlyoutPage
+ {
+ public iOSHideHomeIndicatorFlyoutPageDemo()
+ {
+ Flyout = new ContentPage()
+ {
+ Title = "Detail",
+ Content = new StackLayout()
+ {
+ Children = {
+ new Button()
+ {
+ Text = "Open page 1",
+ Command = new Command(() => Detail = OpenPage("Page 1"))
+ },
+ new Button()
+ {
+ Text = "Open page 2",
+ Command = new Command(() => Detail = OpenPage("Page 2"))
+ }
+ }
+ }
+ };
+
+ Detail = OpenPage("Page 1");
+ }
+
+ public ContentPage OpenPage(string title)
+ {
+ return new ContentPage()
+ {
+ Title = title,
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children = {
+ new Button
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ },
+ new Button()
+ {
+ Text = "Click to open the flyout",
+ Command = new Command(() => IsPresented = true)
+ },
+ new Button
+ {
+ VerticalOptions = LayoutOptions.End,
+ Text = "Back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ }
+ };
+ }
+ }
+
+ public class iOSHideHomeIndicatorPageDemo : Microsoft.Maui.Controls.TabbedPage
+ {
+ public iOSHideHomeIndicatorPageDemo()
+ {
+
+ Children.Add
+ (
+ new ContentPage()
+ {
+ Title = "Tab 1",
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children =
+ {
+ new Button()
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ },
+ new Button()
+ {
+ Text = "Navigate back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ }
+ }
+ );
+
+ Children.Add
+ (
+ new ContentPage()
+ {
+ Title = "Tab 2",
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children =
+ {
+ new Button()
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ },
+ new Button()
+ {
+ Text = "Navigate back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ }
+ }
+ );
+
+ }
+ }
+
+ public class iOSHideHomeIndicatorShellDemo : Shell
+ {
+ public iOSHideHomeIndicatorShellDemo()
+ {
+ TabBar tabBar = new TabBar();
+
+ var toggleHomeIndicatorButton1 = new Button()
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ };
+
+ var contentPage1 = new ContentPage
+ {
+ Title = "Shell Tab 1",
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children =
+ {
+ toggleHomeIndicatorButton1,
+ new Button()
+ {
+ Text = "Navigate back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ }
+ };
+
+ toggleHomeIndicatorButton1.Command = new Command(() => contentPage1.On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()));
+
+ tabBar.Items.Add
+ (
+ new Tab
+ {
+ Title = "Shell Tab 1",
+ Items = {
+ new ShellContent
+ {
+ Content = contentPage1,
+ Title = "Shell Tab 1",
+ }
+ }
+ }
+ );
+
+ var toggleHomeIndicatorButton2 = new Button()
+ {
+ Text = "Toggle Home Indicator",
+ Command = new Command(() => On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()))
+ };
+
+ var contentPage2 = new ContentPage
+ {
+ Title = "Shell Tab 2",
+ Content = new StackLayout()
+ {
+ Margin = new Microsoft.Maui.Thickness(20),
+ Children =
+ {
+ toggleHomeIndicatorButton2,
+ new Button()
+ {
+ Text = "Navigate back",
+ Command = new Command(() => Navigation.PopAsync())
+ }
+ }
+ }
+ };
+
+ toggleHomeIndicatorButton2.Command = new Command(() => contentPage2.On().SetPrefersHomeIndicatorAutoHidden(!On().PrefersHomeIndicatorAutoHidden()));
+
+ tabBar.Items.Add
+ (
+ new Tab
+ {
+ Title = "Shell Tab 2",
+ Items = {
+ new ShellContent
+ {
+ Content = contentPage2,
+ Title = "Shell Tab 2",
+ }
+ }
+ }
+ );
+
+ Items.Add(tabBar);
}
}
}
diff --git a/src/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cs
index c35ce5927093..ee420a4eac33 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/FlyoutPage/iOS/PhoneFlyoutPageRenderer.cs
@@ -198,6 +198,7 @@ bool shouldReceive(UIGestureRecognizer g, UITouch t)
UpdatePanGesture();
UpdateApplyShadow(((FlyoutPage)Element).OnThisPlatform().GetApplyShadow());
+ UpdatePageSpecifics();
}
public override void ViewWillTransitionToSize(CoreGraphics.CGSize toSize, IUIViewControllerTransitionCoordinator coordinator)
@@ -364,6 +365,9 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
UpdateBackground();
else if (e.PropertyName == PlatformConfiguration.iOSSpecific.FlyoutPage.ApplyShadowProperty.PropertyName)
UpdateApplyShadow(((FlyoutPage)Element).OnThisPlatform().GetApplyShadow());
+ else if (e.PropertyName == PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty.PropertyName ||
+ e.PropertyName == PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty.PropertyName)
+ UpdatePageSpecifics();
}
void LayoutChildren(bool animated)
@@ -551,6 +555,7 @@ void UpdateFlyoutPageContainers()
detailRenderer.ViewController.View.Superview.BackgroundColor = Microsoft.Maui.Graphics.Colors.Black.ToPlatform();
ToggleAccessibilityElementsHidden();
+ UpdatePageSpecifics();
}
void UpdateLeftBarButton()
@@ -573,6 +578,12 @@ void UpdateApplyShadow(bool value)
_applyShadow = value;
}
+ void UpdatePageSpecifics()
+ {
+ ChildViewControllerForHomeIndicatorAutoHidden.SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ ChildViewControllerForStatusBarHidden().SetNeedsStatusBarAppearanceUpdate();
+ }
+
public override UIViewController ChildViewControllerForStatusBarHidden()
{
if (((FlyoutPage)Element).Detail?.Handler is IPlatformViewHandler nvh)
diff --git a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
index cd75ac067e30..84ba561a93f8 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/NavigationPage/iOS/NavigationRenderer.cs
@@ -499,6 +499,14 @@ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
{
UpdateHideNavigationBarSeparator();
}
+ else if (e.PropertyName == PrefersHomeIndicatorAutoHiddenProperty.PropertyName)
+ {
+ UpdateHomeIndicatorAutoHidden();
+ }
+ else if (e.PropertyName == PrefersStatusBarHiddenProperty.PropertyName)
+ {
+ UpdateStatusBarHidden();
+ }
}
void ValidateNavbarExists(Page newCurrentPage)
@@ -509,6 +517,22 @@ void ValidateNavbarExists(Page newCurrentPage)
View.InvalidateMeasure(Element);
}
+ void UpdateHomeIndicatorAutoHidden()
+ {
+ if (Element == null)
+ return;
+
+ SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ }
+
+ void UpdateStatusBarHidden()
+ {
+ if (Element == null)
+ return;
+
+ SetNeedsStatusBarAppearanceUpdate();
+ }
+
void UpdateHideNavigationBarSeparator()
{
bool shouldHide = NavPage.OnThisPlatform().HideNavigationBarSeparator();
@@ -1483,6 +1507,7 @@ void UpdatePrefersStatusBarHidden()
{
View.SetNeedsLayout();
ParentViewController?.View.SetNeedsLayout();
+ SetNeedsStatusBarAppearanceUpdate();
}
void TrackerOnCollectionChanged(object sender, EventArgs eventArgs)
diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutRenderer.cs
index b51dfd090692..2bf288734638 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutRenderer.cs
@@ -44,6 +44,12 @@ void IAppearanceObserver.OnAppearanceChanged(ShellAppearance appearance)
UIViewController IShellFlyoutRenderer.ViewController => this;
+ public override bool PrefersHomeIndicatorAutoHidden => Detail.PrefersHomeIndicatorAutoHidden;
+
+ public override bool PrefersStatusBarHidden() => Detail.PrefersStatusBarHidden();
+
+ public override UIStatusBarAnimation PreferredStatusBarUpdateAnimation => Detail.PreferredStatusBarUpdateAnimation;
+
void IShellFlyoutRenderer.AttachFlyout(IShellContext context, UIViewController content)
{
Context = context;
diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs
index dd5b0e3fe987..d66a7abb8002 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellRenderer.cs
@@ -5,6 +5,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Maui.Controls.Platform;
using Microsoft.Maui.Controls.Platform.Compatibility;
+using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
using Microsoft.Maui.Graphics;
using UIKit;
@@ -21,6 +22,29 @@ public ShellRenderer()
}
+ public override bool PrefersHomeIndicatorAutoHidden
+ => Shell?.CurrentPage?.OnThisPlatform()?.PrefersHomeIndicatorAutoHidden() ?? base.PrefersHomeIndicatorAutoHidden;
+
+
+ public override bool PrefersStatusBarHidden()
+ => Shell?.CurrentPage?.OnThisPlatform()?.PrefersStatusBarHidden() == StatusBarHiddenMode.True;
+
+ public override UIKit.UIStatusBarAnimation PreferredStatusBarUpdateAnimation
+ {
+ get
+ {
+ var mode = Shell?.CurrentPage?.OnThisPlatform()?.PreferredStatusBarUpdateAnimation();
+ return mode switch
+ {
+ PlatformConfiguration.iOSSpecific.UIStatusBarAnimation.None => UIKit.UIStatusBarAnimation.None,
+ PlatformConfiguration.iOSSpecific.UIStatusBarAnimation.Fade => UIKit.UIStatusBarAnimation.Fade,
+ PlatformConfiguration.iOSSpecific.UIStatusBarAnimation.Slide => UIKit.UIStatusBarAnimation.Slide,
+ _ => base.PreferredStatusBarUpdateAnimation,
+ };
+ }
+ }
+
+
#region IShellContext
bool IShellContext.AllowFlyoutGesture
diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs
index 2e486f9642fb..9321069b3b89 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellSectionRenderer.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using System.Windows.Input;
using Foundation;
+using Microsoft.Maui.Controls.Handlers.Compatibility;
using Microsoft.Maui.Controls.Internals;
using ObjCRuntime;
using UIKit;
@@ -221,6 +222,15 @@ public override void ViewDidLoad()
}
+ public override void ViewDidAppear(bool animated)
+ {
+ base.ViewDidAppear(animated);
+ if (_context is ShellRenderer shellRenderer)
+ {
+ shellRenderer.ViewController.SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ shellRenderer.ViewController.SetNeedsStatusBarAppearanceUpdate();
+ }
+ }
void IDisconnectable.Disconnect()
{
diff --git a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
index 52eda660fd55..0bb751d5a9be 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/TabbedPage/iOS/TabbedRenderer.cs
@@ -88,6 +88,7 @@ public void SetElement(VisualElement element)
UpdateBarTextColor();
UpdateSelectedTabColors();
UpdateBarTranslucent();
+ UpdatePageSpecifics();
}
public UIViewController ViewController
@@ -209,6 +210,8 @@ void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
if (controller == null)
return;
+ SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ SetNeedsStatusBarAppearanceUpdate();
SelectedViewController = controller;
}
else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
@@ -223,8 +226,8 @@ void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
UpdateCurrentPagePreferredStatusBarUpdateAnimation();
else if (e.PropertyName == TabbedPage.SelectedTabColorProperty.PropertyName || e.PropertyName == TabbedPage.UnselectedTabColorProperty.PropertyName)
UpdateSelectedTabColors();
- else if (e.PropertyName == PrefersHomeIndicatorAutoHiddenProperty.PropertyName)
- UpdatePrefersHomeIndicatorAutoHiddenOnPages();
+ else if (e.PropertyName == PrefersHomeIndicatorAutoHiddenProperty.PropertyName || e.PropertyName == PrefersStatusBarHiddenProperty.PropertyName)
+ UpdatePageSpecifics();
else if (e.PropertyName == TabbedPageConfiguration.TranslucencyModeProperty.PropertyName)
UpdateBarTranslucent();
@@ -265,13 +268,10 @@ public override UIViewController ChildViewControllerForHomeIndicatorAutoHidden
}
}
- void UpdatePrefersHomeIndicatorAutoHiddenOnPages()
+ void UpdatePageSpecifics()
{
- bool isHomeIndicatorHidden = Tabbed.OnThisPlatform().PrefersHomeIndicatorAutoHidden();
- for (var i = 0; i < ViewControllers.Length; i++)
- {
- Tabbed.GetPageByIndex(i).OnThisPlatform().SetPrefersHomeIndicatorAutoHidden(isHomeIndicatorHidden);
- }
+ ChildViewControllerForHomeIndicatorAutoHidden.SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ ChildViewControllerForStatusBarHidden().SetNeedsStatusBarAppearanceUpdate();
}
void Reset()
diff --git a/src/Controls/src/Core/ContentPage/ContentPage.Mapper.cs b/src/Controls/src/Core/ContentPage/ContentPage.Mapper.cs
index 9b5de3ad62a0..c3d425d12c4d 100644
--- a/src/Controls/src/Core/ContentPage/ContentPage.Mapper.cs
+++ b/src/Controls/src/Core/ContentPage/ContentPage.Mapper.cs
@@ -12,8 +12,24 @@ public partial class ContentPage
internal new static void RemapForControls()
{
PageHandler.Mapper.ReplaceMapping(nameof(ContentPage.HideSoftInputOnTapped), MapHideSoftInputOnTapped);
+#if IOS
+ PageHandler.Mapper.ReplaceMapping(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty.PropertyName, MapPrefersHomeIndicatorAutoHidden);
+ PageHandler.Mapper.ReplaceMapping(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty.PropertyName, MapPrefersStatusBarHidden);
+#endif
}
+#if IOS
+ static void MapPrefersHomeIndicatorAutoHidden(IPageHandler handler, ContentPage page)
+ {
+ handler?.UpdateValue(nameof(IiOSPageSpecifics.IsHomeIndicatorAutoHidden));
+ }
+
+ static void MapPrefersStatusBarHidden(IPageHandler handler, ContentPage page)
+ {
+ handler?.UpdateValue(nameof(IiOSPageSpecifics.PrefersStatusBarHiddenMode));
+ }
+#endif
+
static void MapHideSoftInputOnTapped(IPageHandler handler, ContentPage page)
{
page.UpdateHideSoftInputOnTapped();
diff --git a/src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs b/src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs
index 0cb182bf0076..a19abe485580 100644
--- a/src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs
+++ b/src/Controls/src/Core/FlyoutPage/FlyoutPage.Mapper.cs
@@ -12,11 +12,27 @@ public partial class FlyoutPage
internal new static void RemapForControls()
{
FlyoutViewHandler.Mapper.ReplaceMapping(nameof(FlyoutLayoutBehavior), MapFlyoutLayoutBehavior);
+#if IOS
+ FlyoutViewHandler.Mapper.ReplaceMapping(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty), MapPrefersHomeIndicatorAutoHiddenProperty);
+ FlyoutViewHandler.Mapper.ReplaceMapping(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty), MapPrefersPrefersStatusBarHiddenProperty);
+#endif
}
internal static void MapFlyoutLayoutBehavior(IFlyoutViewHandler handler, IFlyoutView view)
{
handler.UpdateValue(nameof(IFlyoutView.FlyoutBehavior));
}
+
+#if IOS
+ internal static void MapPrefersHomeIndicatorAutoHiddenProperty(IFlyoutViewHandler handler, IFlyoutView view)
+ {
+ handler.UpdateValue(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty));
+ }
+
+ internal static void MapPrefersPrefersStatusBarHiddenProperty(IFlyoutViewHandler handler, IFlyoutView view)
+ {
+ handler.UpdateValue(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty));
+ }
+#endif
}
}
diff --git a/src/Controls/src/Core/Page/Page.cs b/src/Controls/src/Core/Page/Page.cs
index e86197a2a1ba..4d5797987ab6 100644
--- a/src/Controls/src/Core/Page/Page.cs
+++ b/src/Controls/src/Core/Page/Page.cs
@@ -19,6 +19,9 @@ namespace Microsoft.Maui.Controls
/// is primarily a base class for more useful derived types. Objects that are derived from the class are most prominently used as the top level UI element in .NET MAUI applications. In addition to their role as the main pages of applications, objects and their descendants can be used with navigation classes, such as or , among others, to provide rich user experiences that conform to the expected behaviors on each platform.
///
public partial class Page : VisualElement, ILayout, IPageController, IElementConfiguration, IPaddingElement, ISafeAreaView, ISafeAreaView2, IView, ITitledElement, IToolbarElement
+#if IOS
+ ,IiOSPageSpecifics
+#endif
{
///
/// The identifier used by the internal messaging system to set .
@@ -207,6 +210,44 @@ public bool IgnoresContainerArea
///
bool ISafeAreaView.IgnoreSafeArea => !On().UsingSafeArea();
+#if IOS
+ ///
+ bool IiOSPageSpecifics.IsHomeIndicatorAutoHidden
+ {
+ get
+ {
+ if (Parent is Page page && page.IsSet(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty))
+ return page.On().PrefersHomeIndicatorAutoHidden();
+
+ return On().PrefersHomeIndicatorAutoHidden();
+ }
+ }
+
+ ///
+ int IiOSPageSpecifics.PrefersStatusBarHiddenMode
+ {
+ get
+ {
+ if (Parent is Page page && page.IsSet(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty))
+ return (int)page.On().PrefersStatusBarHidden();
+
+ return (int)On().PrefersStatusBarHidden();
+ }
+ }
+
+ ///
+ int IiOSPageSpecifics.PreferredStatusBarUpdateAnimationMode
+ {
+ get
+ {
+ if (Parent is Page page && page.IsSet(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty))
+ return (int)page.On().PreferredStatusBarUpdateAnimation();
+
+ return (int)On().PreferredStatusBarUpdateAnimation();
+ }
+ }
+#endif
+
///
Thickness ISafeAreaView2.SafeAreaInsets
{
diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index 8624bfa2abd2..73b19b6a1f68 100644
--- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -1,4 +1,6 @@
#nullable enable
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersStatusBarHidden() -> bool
override Microsoft.Maui.Controls.GradientBrush.IsEmpty.get -> bool
override Microsoft.Maui.Controls.Label.ArrangeOverride(Microsoft.Maui.Graphics.Rect bounds) -> Microsoft.Maui.Graphics.Size
Microsoft.Maui.Controls.DropCompletedEventArgs.PlatformArgs.get -> Microsoft.Maui.Controls.PlatformDropCompletedEventArgs?
@@ -75,6 +77,11 @@ Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommand.set -> v
Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandParameter.get -> object!
Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandParameter.set -> void
override Microsoft.Maui.Controls.Handlers.Items.ItemsViewController.LoadView() -> void
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PrefersStatusBarHidden() -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.ViewDidAppear(bool animated) -> void
static readonly Microsoft.Maui.Controls.KeyboardAccelerator.KeyProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.KeyboardAccelerator.ModifiersProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.DragGestureRecognizer.CanDragProperty -> Microsoft.Maui.Controls.BindableProperty!
diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 808cf70ddd63..caa61b6d473d 100644
--- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -1,6 +1,8 @@
#nullable enable
override Microsoft.Maui.Controls.GradientBrush.IsEmpty.get -> bool
override Microsoft.Maui.Controls.Label.ArrangeOverride(Microsoft.Maui.Graphics.Rect bounds) -> Microsoft.Maui.Graphics.Size
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersStatusBarHidden() -> bool
Microsoft.Maui.Controls.PlatformDragStartingEventArgs
Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragInteraction.get -> UIKit.UIDragInteraction!
Microsoft.Maui.Controls.PlatformDragStartingEventArgs.DragSession.get -> UIKit.IUIDragSession!
@@ -85,6 +87,11 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerPressedC
static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerPressedCommandProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandParameterProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandProperty -> Microsoft.Maui.Controls.BindableProperty!
+override Microsoft.Maui.Controls.Handlers.Compatibility.ShellRenderer.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.PrefersStatusBarHidden() -> bool
+override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.ViewDidAppear(bool animated) -> void
virtual Microsoft.Maui.Controls.DragEventArgs.GetPosition(Microsoft.Maui.Controls.Element? relativeTo) -> Microsoft.Maui.Graphics.Point?
virtual Microsoft.Maui.Controls.DragStartingEventArgs.GetPosition(Microsoft.Maui.Controls.Element? relativeTo) -> Microsoft.Maui.Graphics.Point?
virtual Microsoft.Maui.Controls.DropEventArgs.GetPosition(Microsoft.Maui.Controls.Element? relativeTo) -> Microsoft.Maui.Graphics.Point?
diff --git a/src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs b/src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs
index 7d10e3ac52e7..8dc05d087a72 100644
--- a/src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs
+++ b/src/Controls/src/Core/TabbedPage/TabbedPage.Mapper.cs
@@ -29,6 +29,11 @@ public partial class TabbedPage
#if WINDOWS || ANDROID || TIZEN
TabbedViewHandler.PlatformViewFactory = OnCreatePlatformView;
#endif
+
+#if IOS
+ TabbedViewHandler.Mapper.ReplaceMapping(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty), MapPrefersHomeIndicatorAutoHiddenProperty);
+ TabbedViewHandler.Mapper.ReplaceMapping(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty), MapPrefersPrefersStatusBarHiddenProperty);
+#endif
}
}
}
diff --git a/src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs b/src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
index 5093c7e31b08..f221e2f31226 100644
--- a/src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
+++ b/src/Controls/src/Core/TabbedPage/TabbedPage.iOS.cs
@@ -38,5 +38,15 @@ internal static void MapCurrentPage(ITabbedViewHandler handler, TabbedPage view)
{
}
+
+ internal static void MapPrefersHomeIndicatorAutoHiddenProperty(ITabbedViewHandler handler, TabbedPage view)
+ {
+ view.CurrentPage.Handler.UpdateValue(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersHomeIndicatorAutoHiddenProperty));
+ }
+
+ internal static void MapPrefersPrefersStatusBarHiddenProperty(ITabbedViewHandler handler, TabbedPage view)
+ {
+ view.CurrentPage.Handler.UpdateValue(nameof(PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty));
+ }
}
}
diff --git a/src/Core/src/Handlers/Page/PageHandler.cs b/src/Core/src/Handlers/Page/PageHandler.cs
index dfbae9a27359..1befa32a508d 100644
--- a/src/Core/src/Handlers/Page/PageHandler.cs
+++ b/src/Core/src/Handlers/Page/PageHandler.cs
@@ -8,6 +8,10 @@ public partial class PageHandler : ContentViewHandler, IPageHandler
{
#if IOS || TIZEN
[nameof(IContentView.Background)] = MapBackground,
+#if IOS
+ [nameof(IiOSPageSpecifics.IsHomeIndicatorAutoHidden)] = MapHomeIndicatorAutoHidden,
+ [nameof(IiOSPageSpecifics.PrefersStatusBarHiddenMode)] = MapPrefersStatusBarHiddenMode,
+#endif
#endif
[nameof(ITitledElement.Title)] = MapTitle,
};
diff --git a/src/Core/src/Handlers/Page/PageHandler.iOS.cs b/src/Core/src/Handlers/Page/PageHandler.iOS.cs
index cedec45953ac..2a11d919ed8a 100644
--- a/src/Core/src/Handlers/Page/PageHandler.iOS.cs
+++ b/src/Core/src/Handlers/Page/PageHandler.iOS.cs
@@ -30,6 +30,22 @@ public static void MapBackground(IPageHandler handler, IContentView page)
}
}
+ internal static void MapHomeIndicatorAutoHidden(IPageHandler handler, IContentView page)
+ {
+ if (handler is IPlatformViewHandler platformViewHandler && platformViewHandler.ViewController is not null)
+ {
+ platformViewHandler.ViewController.SetNeedsUpdateOfHomeIndicatorAutoHidden();
+ }
+ }
+
+ internal static void MapPrefersStatusBarHiddenMode(IPageHandler handler, IContentView page)
+ {
+ if (handler is IPlatformViewHandler platformViewHandler && platformViewHandler.ViewController is not null)
+ {
+ platformViewHandler.ViewController.SetNeedsStatusBarAppearanceUpdate();
+ }
+ }
+
public static void MapTitle(IPageHandler handler, IContentView page)
{
if (handler is IPlatformViewHandler platformViewHandler && platformViewHandler.ViewController is not null)
diff --git a/src/Core/src/Platform/iOS/IiOSPageSpecifics.cs b/src/Core/src/Platform/iOS/IiOSPageSpecifics.cs
new file mode 100644
index 000000000000..21b8ac9e098c
--- /dev/null
+++ b/src/Core/src/Platform/iOS/IiOSPageSpecifics.cs
@@ -0,0 +1,26 @@
+namespace Microsoft.Maui.Platform;
+
+///
+/// Provides functionality for requesting hiding the home indicator on the device screen.
+///
+///
+/// This interface may be applied to IContentView.
+/// This interface is only recognized on the iOS platform; other platforms will ignore it.
+///
+internal interface IiOSPageSpecifics
+{
+ ///
+ /// Gets a Boolean value that, if true, hides the HomeIndicator.
+ ///
+ bool IsHomeIndicatorAutoHidden { get; }
+
+ ///
+ /// Gets the preferred mode for the status bar.
+ ///
+ int PrefersStatusBarHiddenMode { get; }
+
+ ///
+ /// Gets the preferred animation for updating the status bar.
+ ///
+ int PreferredStatusBarUpdateAnimationMode { get; }
+}
\ No newline at end of file
diff --git a/src/Core/src/Platform/iOS/PageViewController.cs b/src/Core/src/Platform/iOS/PageViewController.cs
index b87255cce3e3..01b653bb4c01 100644
--- a/src/Core/src/Platform/iOS/PageViewController.cs
+++ b/src/Core/src/Platform/iOS/PageViewController.cs
@@ -21,6 +21,41 @@ protected override UIView CreatePlatformView(IElement view)
};
}
+ public override bool PrefersHomeIndicatorAutoHidden
+ => CurrentView is IiOSPageSpecifics pageSpecifics && pageSpecifics.IsHomeIndicatorAutoHidden;
+
+ public override bool PrefersStatusBarHidden()
+ {
+ if(CurrentView is IiOSPageSpecifics pageSpecifics)
+ {
+ return pageSpecifics.PrefersStatusBarHiddenMode switch
+ {
+ 1 => true,
+ 2 => false,
+ _ => base.PrefersStatusBarHidden(),
+ };
+ }
+
+ return base.PrefersStatusBarHidden();
+ }
+
+ public override UIStatusBarAnimation PreferredStatusBarUpdateAnimation
+ {
+ get
+ {
+ if (CurrentView is IiOSPageSpecifics pageSpecifics)
+ {
+ return pageSpecifics.PreferredStatusBarUpdateAnimationMode switch
+ {
+ 0 => UIStatusBarAnimation.Fade,
+ 1 => UIStatusBarAnimation.Slide,
+ _ => UIStatusBarAnimation.None,
+ };
+ }
+ return base.PreferredStatusBarUpdateAnimation;
+ }
+ }
+
public override void TraitCollectionDidChange(UITraitCollection? previousTraitCollection)
{
if (CurrentView?.Handler is ElementHandler handler)
diff --git a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index 7e2017867d3f..bb6889c295aa 100644
--- a/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -81,6 +81,9 @@ override Microsoft.Maui.Platform.MauiView.LayoutSubviews() -> void
override Microsoft.Maui.Platform.MauiView.SetNeedsLayout() -> void
override Microsoft.Maui.Platform.MauiView.SizeThatFits(CoreGraphics.CGSize size) -> CoreGraphics.CGSize
override Microsoft.Maui.Platform.NoCaretField.MovedToWindow() -> void
+override Microsoft.Maui.Platform.PageViewController.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Platform.PageViewController.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Platform.PageViewController.PrefersStatusBarHidden() -> bool
override Microsoft.Maui.Platform.WrapperView.MovedToWindow() -> void
override Microsoft.Maui.SizeRequest.Equals(object? obj) -> bool
override Microsoft.Maui.SizeRequest.GetHashCode() -> int
diff --git a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 4baaf01d90b2..90a3bfd766e5 100644
--- a/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Core/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -83,6 +83,9 @@ override Microsoft.Maui.Platform.MauiTextView.Font.set -> void
override Microsoft.Maui.Platform.MauiView.LayoutSubviews() -> void
override Microsoft.Maui.Platform.MauiView.SetNeedsLayout() -> void
override Microsoft.Maui.Platform.MauiView.SizeThatFits(CoreGraphics.CGSize size) -> CoreGraphics.CGSize
+override Microsoft.Maui.Platform.PageViewController.PreferredStatusBarUpdateAnimation.get -> UIKit.UIStatusBarAnimation
+override Microsoft.Maui.Platform.PageViewController.PrefersHomeIndicatorAutoHidden.get -> bool
+override Microsoft.Maui.Platform.PageViewController.PrefersStatusBarHidden() -> bool
override Microsoft.Maui.Platform.NoCaretField.MovedToWindow() -> void
override Microsoft.Maui.Platform.WrapperView.MovedToWindow() -> void
override Microsoft.Maui.SizeRequest.Equals(object? obj) -> bool