Xamarin.forms: [Enhancement] Set StatusBar color for iOS and Android from any Page

Created on 29 Aug 2019  Â·  9Comments  Â·  Source: xamarin/Xamarin.Forms

Summary

Now this is only possible in NavigationPage.
I suggest making it accessible from any page.

API Changes

Page.SetStatusBarColor(Color color);
Page.SetStatusBarLightTheme();
Page.SetStatusBarDarkTheme();

or

enum StatusBarTheme
{
    Light,
    Dark,
}
Page.SetStatusBarColor(StatusBarTheme theme);
in-progress high impact mobcat proposal-open enhancement âž•

Most helpful comment

We urgently need this. Especially if you don't want to show the NavigationBar, it becomes quite tricky. This is absolutely necessary in so many scenarios. I, for example, need to change the bar-color in a ContentPage inside of a NavigationPage that itself is a child of a TabbedPage. I've optimized the app for Dark Mode, but the StatusBar is really troubling me. The font on the status bar automatically goes white on Dark Mode, leaving me with white text on white background. Not exactly ideal...

All 9 comments

I've done this via Dependency

Interface

public interface IStatusBar
   {
      void SetColor(string hexColor);
   }

Android

public void SetColor(string hexColor)
      {
         var activity = Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity as MainActivity;
         activity.SetStatusColor(hexColor);
      }

iOS

 public void SetColor(string hexColor)
      {
         var statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
         if (statusBar.RespondsToSelector(new ObjCRuntime.Selector("setBackgroundColor:")))
            statusBar.BackgroundColor = Color.FromHex(hexColor);
      }

Then you set the color from a viewmodel via:
DependencyService.Get<IStatusBar>()?.SetColor(#845754);

nice @galadril

Great idea!
Just be careful, the iOS implementation is now obsolete with iOS 13.

Thanks for the info @cyrilcathala, can you describe it more detailed? or maybe you have a link?

This kind of issue: https://stackoverflow.com/questions/56651245/how-to-change-the-status-bar-background-color-and-text-color-on-ios-13

I kinda tweaked the solution into this (which feels very hacky and dirty):

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
     [...]
     Xamarin.Forms.Forms.ViewInitialized += Forms_ViewInitialized;
     [...]
}

private void Forms_ViewInitialized(object sender, Xamarin.Forms.ViewInitializedEventArgs e)
        {
            if (e.View is Page)
            {
                UpdateStatusBar();
            }
        }

private void UpdateStatusBar()
        {
            var statusBarColor = UIColor.FromRGB(34, 84, 168); // #2254A8

            if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                foreach (var window in UIApplication.SharedApplication.Windows)
                {
                    const int statusBarTag = 38482;

                    if (window.ViewWithTag(statusBarTag) != null) continue;

                    var statusBar = new UIView(UIApplication.SharedApplication.StatusBarFrame);
                    statusBar.Tag = 38482;
                    statusBar.BackgroundColor = statusBarColor;
                    window.AddSubview(statusBar);
                }
            }
            else
            {
                var statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;
                if (statusBar.RespondsToSelector(new Selector("setBackgroundColor:")))
                {
                    statusBar.BackgroundColor = statusBarColor;
                }
            }
        }

@cyrilcathala I think this works as well:

if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                Window = new UIWindow(UIScreen.MainScreen.Bounds)
                {
                    RootViewController = new UIViewController()
                };

                Window.MakeKeyAndVisible();

                statusBar = new UIView(UIApplication.SharedApplication.StatusBarFrame)
                {
                    BackgroundColor = UIColor.Black,
                    TintColor = UIColor.White,
                };

                UIApplication.SharedApplication.Delegate.GetWindow().AddSubview(statusBar);
            }
            else
            {
                statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBarWindow")).ValueForKey(new NSString("statusBar")) as UIView;
                statusBar.BackgroundColor = UIColor.Black;
                statusBar.TintColor = UIColor.White;
            }
...

public override UIWindow Window
        {
            get;
            set;
        }

@LeoJHarris I'm not sure your implementation works well for Forms. And you should try displaying a modal, I think it won't work either.

We urgently need this. Especially if you don't want to show the NavigationBar, it becomes quite tricky. This is absolutely necessary in so many scenarios. I, for example, need to change the bar-color in a ContentPage inside of a NavigationPage that itself is a child of a TabbedPage. I've optimized the app for Dark Mode, but the StatusBar is really troubling me. The font on the status bar automatically goes white on Dark Mode, leaving me with white text on white background. Not exactly ideal...

so, it will be included only in .NET MAUI?

Was this page helpful?
0 / 5 - 0 ratings