Skip to content

Commit

Permalink
[iOS] StatusBarBehavior does not occupy entire notch - fix (#2309)
Browse files Browse the repository at this point in the history
* [iOS] Improve status bar

* Use `Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.Page.GetUseSafeArea`, Remove `CommunityToolkit.Maui.PlatformConfiguration.iOSSpecific.StatusBar`, Remove `OperatingSystem.IsIOSVersionAtLeast(13))` (Toolkit now supports iOS 15+)

* Remove iOS 13 check (Toolkit only supports iOS 15+)

* Don't modify StatusBar Frame in `PlatformSetColor`

* Remove iOS 13 code (Toolkit support iOS 15+

* Refactor

* Update azure-pipelines.yml

---------

Co-authored-by: Brandon Minnick <[email protected]>
  • Loading branch information
kubaflo and TheCodeTraveler authored Jan 16, 2025
1 parent 075be1b commit 46fb9a2
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 96 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ variables:
PathToCommunityToolkitAnalyzersBenchmarkCsproj: 'src/CommunityToolkit.Maui.Analyzers.Benchmarks/CommunityToolkit.Maui.Analyzers.Benchmarks.csproj'
DotNetMauiRollbackFile: 'https://maui.blob.core.windows.net/metadata/rollbacks/8.0.6.json'
CommunityToolkitSampleApp_Xcode_Version: '16.2'
CommunityToolkitLibrary_Xcode_Version: '16.1'
CommunityToolkitLibrary_Xcode_Version: '16.2'

trigger:
branches:
Expand Down
7 changes: 2 additions & 5 deletions samples/CommunityToolkit.Maui.Sample/Pages/Base/BasePage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@

namespace CommunityToolkit.Maui.Sample.Pages;

public abstract class BasePage<TViewModel> : BasePage where TViewModel : BaseViewModel
public abstract class BasePage<TViewModel>(TViewModel viewModel) : BasePage(viewModel)
where TViewModel : BaseViewModel
{
protected BasePage(TViewModel viewModel) : base(viewModel)
{
}

public new TViewModel BindingContext => (TViewModel)base.BindingContext;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages"
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Behaviors"
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
ios:Page.UseSafeArea="True"
Title="StatusBarBehavior"
x:DataType="vm:StatusBarBehaviorViewModel"
x:TypeArguments="vm:StatusBarBehaviorViewModel"
Expand Down Expand Up @@ -81,7 +83,7 @@

<ScrollView Padding="{StaticResource ContentPadding}">

<VerticalStackLayout Padding="15,0" Spacing="30">
<VerticalStackLayout Padding="15,0" Spacing="30" IgnoreSafeArea="False">

<Label Text="Slide to change StatusBar color" />

Expand Down
126 changes: 50 additions & 76 deletions src/CommunityToolkit.Maui.Core/Platform/StatusBar/StatusBar.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,73 @@ static partial class StatusBar
/// <summary>
/// Method to update the status bar size.
/// </summary>
public static void UpdateBarSize()
public static void SetBarSize(bool isUsingSafeArea)
{
if (OperatingSystem.IsIOSVersionAtLeast(13))
var communityToolkitStatusBarTag = new IntPtr(38482);
foreach (var window in UIApplication.SharedApplication.Windows)
{
var statusBarTag = new IntPtr(38482);
foreach (var window in UIApplication.SharedApplication.Windows)
var statusBarFrame = window.WindowScene?.StatusBarManager?.StatusBarFrame;
if (statusBarFrame is null)
{
var statusBar = window.ViewWithTag(statusBarTag);
var statusBarFrame = window.WindowScene?.StatusBarManager?.StatusBarFrame;
if (statusBarFrame is null)
{
continue;
}

statusBar ??= new UIView(statusBarFrame.Value);
statusBar.Tag = statusBarTag;
statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
var statusBarSubViews = window.Subviews.Where(x => x.Tag == statusBarTag).ToList();
foreach (var statusBarSubView in statusBarSubViews)
{
statusBarSubView.RemoveFromSuperview();
}

window.AddSubview(statusBar);

TryUpdateStatusBarAppearance(window);
continue;
}
}
else
{
if (UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) is UIView statusBar)

var statusBar = window.ViewWithTag(communityToolkitStatusBarTag) ?? new UIView(statusBarFrame.Value);
statusBar.Tag = communityToolkitStatusBarTag;
statusBar.Frame = GetStatusBarFrame(window, isUsingSafeArea);

var statusBarSubViews = window.Subviews.Where(x => x.Tag == communityToolkitStatusBarTag).ToList();
foreach (var statusBarSubView in statusBarSubViews)
{
statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
statusBarSubView.RemoveFromSuperview();
}

TryUpdateStatusBarAppearance();
window.AddSubview(statusBar);

TryUpdateStatusBarAppearance(window);
}
}

static void PlatformSetColor(Color color)
{
var uiColor = color.ToPlatform();

if (OperatingSystem.IsIOSVersionAtLeast(13))

var statusBarTag = new IntPtr(38482);
foreach (var window in UIApplication.SharedApplication.Windows)
{
var statusBarTag = new IntPtr(38482);
foreach (var window in UIApplication.SharedApplication.Windows)
var statusBar = window.ViewWithTag(statusBarTag);
var statusBarFrame = window.WindowScene?.StatusBarManager?.StatusBarFrame;
if (statusBarFrame is null)
{
var statusBar = window.ViewWithTag(statusBarTag);
var statusBarFrame = window.WindowScene?.StatusBarManager?.StatusBarFrame;
if (statusBarFrame is null)
{
continue;
}

// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
// window.ViewWithTag(tag) can return null
statusBar ??= new UIView(statusBarFrame.Value);
statusBar.Tag = statusBarTag;
statusBar.BackgroundColor = uiColor;
statusBar.TintColor = uiColor;
statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
var statusBarSubViews = window.Subviews.Where(x => x.Tag == statusBarTag).ToList();
foreach (var statusBarSubView in statusBarSubViews)
{
statusBarSubView.RemoveFromSuperview();
}

window.AddSubview(statusBar);

TryUpdateStatusBarAppearance(window);
continue;
}
}
else
{
if (UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) is UIView statusBar
&& statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))

statusBar ??= new UIView(statusBarFrame.Value);
statusBar.Tag = statusBarTag;
statusBar.BackgroundColor = uiColor;
statusBar.TintColor = uiColor;

var statusBarSubViews = window.Subviews.Where(x => x.Tag == statusBarTag).ToList();
foreach (var statusBarSubView in statusBarSubViews)
{
statusBar.BackgroundColor = uiColor;
statusBarSubView.RemoveFromSuperview();
}

TryUpdateStatusBarAppearance();
window.AddSubview(statusBar);

TryUpdateStatusBarAppearance(window);
}
}

static CGRect GetStatusBarFrame(in UIWindow window, in bool isUsingSafeArea)
{
var statusBarFrame = UIApplication.SharedApplication.StatusBarFrame;

return isUsingSafeArea
? new CGRect(statusBarFrame.X, statusBarFrame.Y, statusBarFrame.Width, window.SafeAreaInsets.Top)
: statusBarFrame;
}

static void PlatformSetStyle(StatusBarStyle statusBarStyle)
{
var uiStyle = statusBarStyle switch
Expand All @@ -113,22 +95,14 @@ static void PlatformSetStyle(StatusBarStyle statusBarStyle)

static bool TryUpdateStatusBarAppearance()
{
if (OperatingSystem.IsIOSVersionAtLeast(13))
{
var didUpdateAllStatusBars = true;
var didUpdateAllStatusBars = true;

foreach (var window in UIApplication.SharedApplication.Windows)
{
didUpdateAllStatusBars &= TryUpdateStatusBarAppearance(window);
}

return didUpdateAllStatusBars;
}
else
foreach (var window in UIApplication.SharedApplication.Windows)
{
var window = UIApplication.SharedApplication.KeyWindow;
return TryUpdateStatusBarAppearance(window);
didUpdateAllStatusBars &= TryUpdateStatusBarAppearance(window);
}

return didUpdateAllStatusBars;
}

static bool TryUpdateStatusBarAppearance(UIWindow? window)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,48 +78,53 @@ public StatusBarApplyOn ApplyOn

/// <inheritdoc />
#if IOS
protected override void OnAttachedTo(Page bindable, UIKit.UIView platformView)
protected override void OnAttachedTo(Page page, UIKit.UIView platformView)
#elif ANDROID
protected override void OnAttachedTo(Page bindable, Android.Views.View platformView)
protected override void OnAttachedTo(Page page, Android.Views.View platformView)
#else
protected override void OnAttachedTo(Page bindable, object platformView)
protected override void OnAttachedTo(Page page, object platformView)
#endif
{
base.OnAttachedTo(bindable, platformView);
base.OnAttachedTo(page, platformView);

if (ApplyOn is StatusBarApplyOn.OnBehaviorAttachedTo)
{
#if IOS
StatusBar.SetBarSize(Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.Page.GetUseSafeArea(page));
#endif

StatusBar.SetColor(StatusBarColor);
StatusBar.SetStyle(StatusBarStyle);
}

bindable.NavigatedTo += OnPageNavigatedTo;
page.NavigatedTo += OnPageNavigatedTo;
#if IOS
bindable.SizeChanged += OnPageSizeChanged;
page.SizeChanged += OnPageSizeChanged;
#endif
}

/// <inheritdoc />
#if IOS
protected override void OnDetachedFrom(Page bindable, UIKit.UIView platformView)
protected override void OnDetachedFrom(Page page, UIKit.UIView platformView)
#elif ANDROID
protected override void OnDetachedFrom(Page bindable, Android.Views.View platformView)
protected override void OnDetachedFrom(Page page, Android.Views.View platformView)
#else
protected override void OnDetachedFrom(Page bindable, object platformView)
protected override void OnDetachedFrom(Page page, object platformView)
#endif
{
#if IOS
bindable.SizeChanged -= OnPageSizeChanged;
page.SizeChanged -= OnPageSizeChanged;
#endif
base.OnDetachedFrom(bindable, platformView);
base.OnDetachedFrom(page, platformView);

bindable.NavigatedTo -= OnPageNavigatedTo;
page.NavigatedTo -= OnPageNavigatedTo;
}

#if IOS
static void OnPageSizeChanged(object? sender, EventArgs e)
{
StatusBar.UpdateBarSize();
ArgumentNullException.ThrowIfNull(sender);
StatusBar.SetBarSize(Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific.Page.GetUseSafeArea((Page)sender));
}
#endif

Expand Down

0 comments on commit 46fb9a2

Please sign in to comment.