Change .NET MAUI iOS Status Bar Color (Background)
At the moment I’m working on a little .NET MAUI Blazor app and out of the box the iOS target has a white status bar at the top. I’m no designer, but I don’t like how that looks. In this post I’ll show you how to add a nice status bar color, even when rotating the device!
Problem: No Status Bar Color/Transparent Status Bar #
When you create a new .NET MAUI (Blazor) app there will be a white (or black when Dark Theme is enabled) bar on top of your screen. This really doesn’t have much to do with the fact that it’s .NET MAUI, this is just how iOS works. It’s not just white, it’s transparent even. If you scroll the Blazor content all the way to the top you can see the content appearing above the top bar of our Blazor content. You can see what that looks like below. Time to fix that!
Change the iOS Status Bar Color… But with Xamarin.Forms #
Actually we won’t actually change the status bar, we place a view behind the status bar. David Ortinau has a great 60 second video on how to do it for Xamarin.Forms, but! We are now on .NET MAUI, so let’s see how to do it there.
I first tried to port the code from David (see below) to .NET MAUI, but it seems something has changed in the lifecycle of things and I kept running into issues.
The issue I kept running into is that
UIApplication.SharedApplication.Windows.FirstOrDefault(); would yield no result. On the one hand because that API seems to be deprecated since iOS 13 and on the other hand, or maybe because of that deprecation, that it would just give me
null indicating that something might have changed in .NET MAUI lifecycles and when that window was created.
While trying to figure out how to get it to work, I found that .NET MAUI has great support for different lifecycle events now, and I could totally leverage that!
Change Status Bar Color with .NET MAUI! #
With my newly acquired knowledge about the lifecycles in .NET MAUI I went ahead and opened the
App.xaml.cs file and added an override for the
CreateWindow event. At this point the window should be created, so now at least I knew that should not be a problem anymore, but there is still the deprecation of that iOS API.
With some search engine magic I found out that you’re now supposed to use the
Windows property on the right scene. In .NET MAUI (or .NET for iOS for that matter) you can do that by using
UIApplication.SharedApplication.Delegate.GetWindow();. Now to make sure it works great on both iOS 13+ as well as earlier iOS versions, I added some code for the old and the new APIs.
You can review the full code that I implemented below. Make sure to read the text below the code, because there are some extra things I want to point out.
In all this code you will notice that I’m tracking whenever the orientation of the device changes. For iOS, when you hold it in landscape on a phone, there will be no status bar visible at all. Without this code, if you would rotate, there would be this weird artefact on the screen. That is because we’re not really doing anything with the status bar directly, we’re just placing a view under it. Now to make this all work, whenever we don’t discover the status bar view (in other words: we’re running for the first time) or if we discover the device is rotated, we reevaluate if and how the status bar view should be recreated. Luckily, iOS gives us the
UIApplication.SharedApplication.StatusBarFrame API that tells us where the status bar is and what the dimensions are.
Compiler Directives?! #
Lastly, you can see how I wrapped all this in
#if __IOS__ compiler directives. This is necessary because this is iOS specific code and of course, I only want to do this for iOS.
Personally, I hate them. But we’ll probably see much more of them since .NET MAUI has the single-project approach. There are definitely ways around them (see the linked video below), but for this case I decided to keep it like this.
Learn how to write platform-specific code without compiler directives in this video
The result of our code can be reviewed in the screenshot below.
In Review #
If you’re coming from Xamarin.Forms there are some different routes you need to discover to do things in .NET MAUI, but once you get used to that it feels much more natural.
I’m really happy with the new lifecycle management in .NET MAUI, let me know if you want to see more content on that.
More content on this blog coming and also make sure to subscribe to my YouTube channel!