How to Check For Dark Mode in Xamarin.Forms

后端 未结 3 1873
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-17 05:56

Now that iOS 13 and Android Q allow the user to enable Dark Mode at the operating system level, how can I check for it in Xamarin.Forms?

I\'ve created this in my Xam

相关标签:
3条回答
  • 2020-12-17 06:35

    For iOS:

    if (UITraitCollection.CurrentTraitCollection.UserInterfaceStyle == UIUserInterfaceStyle.Dark)
    { ... }
    
    0 讨论(0)
  • 2020-12-17 06:36

    UPDATE as of April 2020:

    It is no longer necessary to use platform-specific services to check for light/dark mode in Xamarin.Forms.

    We can now get the current theme directly via:

    OSAppTheme currentTheme = Application.Current.RequestedTheme;
    

    where the RequestedTheme property returns an OSAppTheme enumeration member: Unspecified, Dark, or Light.

    For more info: see documentation and the updated Xamarin.Forms Application.cs code.

    0 讨论(0)
  • 2020-12-17 06:47

    We can use the Xamarin.Forms dependency service to access the platform-specific code from iOS and Android.

    I've gone into more depth here in this blog post: https://codetraveler.io/2019/09/10/check-for-dark-mode-in-xamarin-forms/

    Xamarin.Forms Code

    IEnvironment

    using System.Threading.Tasks;
    
    namespace MyNamespace
    {
        public interface IEnvironment
        {
            Theme GetOperatingSystemTheme();
            Task<Theme> GetOperatingSystemThemeAsync();
        }
    
        public enum Theme { Light, Dark }
    }
    

    App.cs

    using Xamarin.Forms;
    
    namespace MyNamespace
    {
        public App : Application
        {
            // ...
    
            protected override async void OnStart()
            {
                base.OnStart();
    
                Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();
    
                SetTheme(theme);
            }
    
            protected override async void OnResume()
            {
                base.OnResume();
    
                Theme theme = DependencyService.Get<IEnvironment>().GetOperatingSystemTheme();
    
                SetTheme(theme);
            }
    
            void SetTheme(Theme theme)
            {
                //Handle Light Theme & Dark Theme
            }
        }
    }
    

    Xamarin.iOS

    using System;
    using UIKit;
    using Xamarin.Forms;
    using MyNamespace;
    using MyNamespace.iOS;
    
    [assembly: Dependency(typeof(Environment_iOS))]
    namespace MyNamespace.iOS
    {
        public class Environment_iOS : IEnvironment
        { 
            public Theme GetOperatingSystemTheme()
            {
                //Ensure the current device is running 12.0 or higher, because `TraitCollection.UserInterfaceStyle` was introduced in iOS 12.0
                if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
                {
                    var currentUIViewController = GetVisibleViewController();
    
                    var userInterfaceStyle = currentUIViewController.TraitCollection.UserInterfaceStyle;
    
                    switch (userInterfaceStyle)
                    {
                        case UIUserInterfaceStyle.Light:
                            return Theme.Light;
                        case UIUserInterfaceStyle.Dark:
                            return Theme.Dark;
                        default:
                            throw new NotSupportedException($"UIUserInterfaceStyle {userInterfaceStyle} not supported");
                    }
                }
                else
                {
                    return Theme.Light;
                }
            }
    
            // UIApplication.SharedApplication can only be referenced by the Main Thread, so we'll use Device.InvokeOnMainThreadAsync which was introduced in Xamarin.Forms v4.2.0
            public async Task<Theme> GetOperatingSystemThemeAsync() =>
                Device.InvokeOnMainThreadAsync(GetOperatingSystemTheme);
    
            static UIViewController GetVisibleViewController()
            {
                UIViewController viewController = null;
    
                var window = UIApplication.SharedApplication.KeyWindow;
    
                if (window.WindowLevel == UIWindowLevel.Normal)
                    viewController = window.RootViewController;
    
                if (viewController is null)
                {
                    window = UIApplication.SharedApplication
                        .Windows
                        .OrderByDescending(w => w.WindowLevel)
                        .FirstOrDefault(w => w.RootViewController != null && w.WindowLevel == UIWindowLevel.Normal);
    
                    if (window is null)
                        throw new InvalidOperationException("Could not find current view controller.");
    
                    viewController = window.RootViewController;
                }
    
                while (viewController.PresentedViewController != null)
                    viewController = viewController.PresentedViewController;
    
                return viewController;
            }
        }
    }
    

    Xamarin.Android

    using System;
    using System.Threading.Tasks;
    using Android.Content.Res;
    using Plugin.CurrentActivity;
    using Xamarin.Forms;
    
    using MyNamespace;
    using MyNamespace.Android;
    
    [assembly: Dependency(typeof(Environment_Android))]
    namespace MyNamespace.Android
    {
        public class Environment_Android : IEnvironment
        {
            public Task<Theme> GetOperatingSystemThemeAsync()  =>
                Task.FromResult(GetOperatingSystemTheme());
    
            public Theme GetOperatingSystemTheme()
            {
                //Ensure the device is running Android Froyo or higher because UIMode was added in Android Froyo, API 8.0
                if(Build.VERSION.SdkInt >= BuildVersionCodes.Froyo)
                {
                    var uiModeFlags = CrossCurrentActivity.Current.AppContext.Resources.Configuration.UiMode & UiMode.NightMask;
    
                    switch(uiModelFlags)
                    {
                        case UiMode.NightYes:
                            return Theme.Dark;
    
                        case UiMode.NightNo:
                            return Theme.Light;
    
                        default:
                            throw new NotSupportedException($"UiMode {uiModelFlags} not supported");
                    }
                }
                else
                {
                    return Theme.Light;
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题