Maui
Maui copied to clipboard
[Proposal] StatusBarEffect
StatusBarEffect
- [x] Proposed
- [ ] Prototype: Not Started
- [ ] Implementation: Not Started
- [ ] iOS Support
- [ ] Android Support
- [ ] macOS Support
- [ ] Windows Support
- [ ] Unit Tests: Not Started
- [ ] Sample: Not Started
- [ ] Documentation: Not Started
Summary
Set the color and style of the status bar
Detailed Design
StatusBarEffect.shared.cs
public class StatusBarEffect : RoutingEffect
{
public static readonly BindableProperty ColorProperty;
public static readonly BindableProperty StyleProperty;
public static Color GetColor(BindableObject bindable);
public static StatusBarStyle GetStyle(BindableObject bindable);
}
Usage Syntax
XAML Usage
<ContentPage local:StatusBarEffect.Color="Blue">
</ContentPage>
C# Usage
class MyPage : ContentPage
{
public MyPage()
{
StatusBarEffect.SetColor(this, Colors.Black);
}
}
We should hold this until this https://github.com/dotnet/maui/pull/2049 get merged or closed
Would like to implement this, in case issue is unblocked
dotnet/maui#2049 is now closed, can we move forward with thins issue?
This is still blocked by #124
any updates here?
@KSemenenko not yet. I'll circle back on .NET MAUI team to see if this will be in the framework or not
Hi @pictos, what's the state on this one?
I'm a bit confused with the different issues here and in the MAUI project... Are you going to implement it in the CommunityToolkit or will the MAUI team add it directly in MAUI? And has any work on it already started?
I'll need the feature for a customer project... So if nothing has been implemented yet (nor is in the pipeline to do so shortly), any tips on how to implement it myself? I need to set it dynamically (in case the user switches themes on runtime), currently just for iOS and Android.
Thanks in advance :) Any info/help is appreciated!
Hey @EPS-Lac, it's WIP I should have a PR by the end of this week. I hope this can be in the next stable release, if don't I can guide you on how to implement the feature or how to use the nuget generated by the PR.
Let's make sure we wait for this one for the next release. A lot of people are waiting for this one. Unless something really weird happens, then we'll make a release first while we work on this.
@pictos Oh, I thought, I would be assigned to port this one..
Probably since it has been a while we forgot to check if you were still available. On to the next one! 😉
good news :) waiting for it :)
@jfversluis How about https://github.com/CommunityToolkit/Maui/issues/103? =)
The PR linked to this issue will not implement the StatusBarStyle, and it's due to an API change on Apple.
The current way to do this is overriding the preferredStatusBarStyle and we can't do that here... The change should happen in .NET MAUI itself providing a way to control it.
More info here.
IF anyone knows an implementation that works, let me know
public enum StatusBarStyle
{
Default,
LightContent,
DarkContent,
}
private DisplayOrientation _lastOrientation;
protected override Window CreateWindow(IActivationState activationState)
{
Window window = base.CreateWindow(activationState);
window.Created += (s, e) => { UpdateStatusBarColor(); };
window.Destroying += (s, e) =>
{
NSNotificationCenter.DefaultCenter.RemoveObserver(new NSString("UIDeviceOrientationDidChangeNotification"));
};
MAUICallback.OnBackgroundColorChanged += MAUICallbackOnOnBackgroundColorChanged;
return window;
}
private void UpdateStatusBarColor()
{
UIView statusBar;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
int tag = 4567890;
UIWindow window = UIApplication.SharedApplication.Delegate.GetWindow();
statusBar = window.ViewWithTag(tag);
if (statusBar == null || statusBar.Frame != UIApplication.SharedApplication.StatusBarFrame)
{
statusBar = statusBar ?? new(UIApplication.SharedApplication.StatusBarFrame);
statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
statusBar.Tag = tag;
window.AddSubview(statusBar);
}
// this is my variable with style
var uiStyle = MAUICallback.StatusBarStyle switch
{
StatusBarStyle.LightContent => UIStatusBarStyle.LightContent,
StatusBarStyle.DarkContent => UIStatusBarStyle.DarkContent,
_ => UIStatusBarStyle.Default
};
UIApplication.SharedApplication.SetStatusBarStyle(uiStyle, false);
}
else
{
statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
}
if (statusBar != null)
{
// TODO Make this color come from somewhere shared
statusBar.BackgroundColor = Color.FromArgb(MAUICallback.CurrentColor).ToUIColor();
}
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("UIDeviceOrientationDidChangeNotification"), NotificationCenter =>
{
// This gets called multiple times on iOS, let's optimize a little bit
if (_lastOrientation != DeviceDisplay.MainDisplayInfo.Orientation)
{
UpdateStatusBarColor();
_lastOrientation = DeviceDisplay.MainDisplayInfo.Orientation;
}
});
}
than call "UpdateStatusBarColor();" when you need to change color. this code from App.xaml.cs
@KSemenenko, first of the all thanks for the code snippet.
The StatusBarStyle get updated? And what place do you override your CreateWindow method?
this is in App.xaml.cs, I also will sent you all my file:
using System.Globalization;
using Winkt.Mobile.Api.Abstractions;
using Winkt.Mobile.Helpers;
using Winkt.Mobile.Managers;
using Winkt.Mobile.Managers.Interfaces;
using Xamarin.CommunityToolkit.Effects;
#if __IOS__
using Foundation;
using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
using UIKit;
#endif
namespace Winkt.Mobile;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
private void MAUICallbackOnOnBackgroundColorChanged(object sender, string e)
{
#if __IOS__
UpdateStatusBarColor();
#endif
}
protected override void OnStart()
{
WinktStaticHelper.GenerateDeviceID();
var apiClient = WinktServiceProvider.GetService<IApiClientService>();
apiClient.AuthApiClient.SetAuthToken(AppSettings.SessionId);
}
protected override void OnResume()
{
var manager = WinktServiceProvider.GetService<IAuthManager>();
_ = manager.ResumeSession();
}
protected override void OnSleep()
{
var manager = WinktServiceProvider.GetService<IAuthManager>();
_ = manager.PauseSession();
}
#if __IOS__
private DisplayOrientation _lastOrientation;
protected override Window CreateWindow(IActivationState activationState)
{
Window window = base.CreateWindow(activationState);
window.Created += (s, e) => { UpdateStatusBarColor(); };
window.Destroying += (s, e) =>
{
NSNotificationCenter.DefaultCenter.RemoveObserver(new NSString("UIDeviceOrientationDidChangeNotification"));
};
MAUICallback.OnBackgroundColorChanged += MAUICallbackOnOnBackgroundColorChanged;
return window;
}
private void UpdateStatusBarColor()
{
UIView statusBar;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
int tag = 4567890;
UIWindow window = UIApplication.SharedApplication.Delegate.GetWindow();
statusBar = window.ViewWithTag(tag);
if (statusBar == null || statusBar.Frame != UIApplication.SharedApplication.StatusBarFrame)
{
statusBar = statusBar ?? new(UIApplication.SharedApplication.StatusBarFrame);
statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
statusBar.Tag = tag;
window.AddSubview(statusBar);
}
var uiStyle = MAUICallback.StatusBarStyle switch
{
StatusBarStyle.LightContent => UIStatusBarStyle.LightContent,
StatusBarStyle.DarkContent => UIStatusBarStyle.DarkContent,
_ => UIStatusBarStyle.Default
};
UIApplication.SharedApplication.SetStatusBarStyle(uiStyle, false);
}
else
{
statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
}
if (statusBar != null)
{
// TODO Make this color come from somewhere shared
statusBar.BackgroundColor = Color.FromArgb(MAUICallback.CurrentColor).ToUIColor();
}
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("UIDeviceOrientationDidChangeNotification"), NotificationCenter =>
{
// This gets called multiple times on iOS, let's optimize a little bit
if (_lastOrientation != DeviceDisplay.MainDisplayInfo.Orientation)
{
UpdateStatusBarColor();
_lastOrientation = DeviceDisplay.MainDisplayInfo.Orientation;
}
});
}
#endif
}
In mine implementation, I have some static class, and event, so it's not best solution for sure.
as you can see, the problem is that this thing works on current page. as in Xamarin.Forms the problem is the same. To completely solve this issue, we need to put these 2 properties in Page class. and then when page changes its IsVisible property (or becomes visible) then we will need to applay these properties to paint the status bar.
well, changing the status bar color works like a charm, with the current implementation that I've for the PR... The StyleBar doesn't, so I can't change the DarkContent to LightContent... From my research is because apple just allows the dynamic in ViewController, when you override the preferredStatusBarStyle method. But we can't do that here, this need to be done on .NET MAUI side.
I'll try this window implementation and see how that works and see if I can abstract that here.
Thanks a lot for all this input @KSemenenko
Maybe it's time to implement our Page? base on Maui Page? and put all logic there?
like CommunityPage ?
because, if Xamarin.Froms I relay need this IsVisible readonly property, to know which page in the screen right now
@KSemenenko I tested your code on my end... And the status bar content keeps in white color. So this doesn't work as well or did something wrong :/ Do you have a project that you can share ?
this is my original PR https://github.com/xamarin/Xamarin.Forms/pull/8298
I will create demo app today, because for me this issue is big blocker, and I will help you as much as need to have this functional :)
@pictos did you add into info.plist
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
@pictos it will take more time, it my first time for custom rendered for MAUI, maybe you have some code, so I can working with it?
Maui-StatusBarStule.zip done iOS works
ios_andoird.zip iOS + and/or I love MAUI :)
so for iOS this is the issue
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Hey @KSemenenko I could confirm it works at runtime. Thanks for the snippet
@pictos in my pr you can also find uwp code. Anyway maybe you need some help?
@KSemenenko yeah, we are porting this feature from XCT, which is based on your Forms PR. The UWP doesn't work because on Maui we use the WinUI3 APIs, and they didn't implement the ability to change the status bar color manually.
@pictos realy? Omg….. it least we will have it for iOS and Android :)
if you need some help with anything just ping me