Buttons and Labels text Not visible in Dark Mode of OSx Mojave.Any delegate Method for identifying the Mode Switching?

680 views Asked by At

My application have some UI issues in Mac Os Mojave.Some labels and buttons text content are not visible when I switched to Dark Mode.So I did one workaroud using following code.

var interfaceStyle = NSUserDefaults.StandardUserDefaults.StringForKey("AppleInterfaceStyle");
if (interfaceStyle == "Dark") {
label.textcolor = NSColor.White;
} 

This fixes the issues,But if I switched back to light mode in between the application is using the label color will not change.I need to restart the application to read the code and displaying the label with default color.

Could Any one faced this issue ? Is there any delegate method that hits when the user changes the Appearance mode(Dark & Light) of Mac Os Mojave ?

2

There are 2 answers

2
SushiHangover On

You can use KVO to track theme changes (AppleInterfaceThemeChangedNotification).

A few class level "constants":

readonly NSString themeKeyString = new NSString("AppleInterfaceThemeChangedNotification");
readonly NSString dark = new NSString("Dark");
readonly Selector modeSelector = new Selector("themeChanged:");

Export method for the ObjC selector to call:

[Export("themeChanged:")]
public void ThemeChanged(NSObject change)
{
    var interfaceStyle = NSUserDefaults.StandardUserDefaults.StringForKey("AppleInterfaceStyle");
    if (interfaceStyle == "Dark")
    {
        Console.WriteLine("Now Dark");
    }
        else
    {
        Console.WriteLine("Now not Dark");
    }
}

Add observer request to notification center:

NSDistributedNotificationCenter.GetDefaultCenter().AddObserver(this, modeSelector, themeKeyString, null);

Note: I typically register this in AppDelegate.DidFinishLaunching

Remove the observer if you no longer need it:

NSDistributedNotificationCenter.GetDefaultCenter().RemoveObserver(this, themeKeyString);

BTW: The NSDistributedNotificationCenter.DefaultCenter.AddObserver helpers/overloads do not work properly in this instance...

0
Ivan Ičin On

At least for me it appears that the last line from SushiHangover's answer causes the crash on macOS Monterey and latest version of Xamarin. What works for me instead is:

NSDistributedNotificationCenter.GetDefaultCenter().RemoveObserver(this);