{"id":45181,"date":"2019-08-30T09:50:16","date_gmt":"2019-08-30T16:50:16","guid":{"rendered":"http:\/\/devblogs.microsoft.com\/xamarin\/?p=45181"},"modified":"2019-09-04T13:05:00","modified_gmt":"2019-09-04T20:05:00","slug":"modernizing-ios-apps-dark-mode-xamarin","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/modernizing-ios-apps-dark-mode-xamarin\/","title":{"rendered":"Modernizing iOS Apps for Dark Mode with Xamarin"},"content":{"rendered":"<p>With iOS 13, Apple introduces dark mode: A system-wide option for light and dark themes. iOS users may now choose the theme or allow iOS to dynamically change appearance based on the environment and time. Xamarin.iOS and Xamarin.Forms deliver native iOS experiences to keep your applications looking shiny and fresh no matter what time of day.<\/p>\n<h2>Turning on Dark Mode<\/h2>\n<p>Before testing that your work to support appearance modes actually works, you\u2019ll need to put your simulator into dark mode. In your chosen iOS 13 simulator, open <strong>Settings<\/strong> and scroll down to <strong>Developer<\/strong>. There you will find a switch for turning dark appearance ON or OFF. It only takes a second to see changes take effect across the entire simulator environment. Now you are ready to customize your app for both modes, as well as see your UI respond instantly!<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-45184\" src=\"http:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_DeveloperSetting.png\" alt=\"Turning on Dark Mode\" width=\"600\" height=\"537\" srcset=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_DeveloperSetting.png 782w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_DeveloperSetting-300x269.png 300w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_DeveloperSetting-768x687.png 768w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/p>\n<p><br><\/p>\n<h2>Assets for Light and Dark Modes<\/h2>\n<p>The iOS Asset Catalog in Visual Studio now supports supplying optional images and colors for each appearance mode. When using this functionality, iOS will automatically choose the appropriate image and color for you. Open your <code>Assets.xcassets<\/code> file in your iOS project and add a <strong>New Image<\/strong> set. Notice you can specify universal, dark, and light images at any of the target resolutions. In this example, there is an image for dark and for light with the name of \u201cMicrosoftLogo\u201d.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-45194\" src=\"http:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_AssetCatalog2.png\" alt=\"Assets for Light and Dark Modes img1\" width=\"800\" height=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_AssetCatalog2.png 2560w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_AssetCatalog2-300x188.png 300w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_AssetCatalog2-768x480.png 768w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_AssetCatalog2-1024x640.png 1024w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>Additionally, notice there are also colors specified for &#8220;BackgroundColor&#8221; and &#8220;TitleColor&#8221;. Those colors are now available by name to be used throughout the application. The &#8220;BackgroundColor&#8221; has been assigned to the background of the view, and the &#8220;TitleColor&#8221; to the label you see on screen.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-45185\" src=\"http:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_01.png\" alt=\"Assets for Light and Dark Modes img2\" width=\"600\" height=\"537\" srcset=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_01.png 782w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_01-300x269.png 300w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_01-768x687.png 768w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/p>\n<p><strong>Docs:<\/strong> <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/ios\/platform\/ios13\/dark-mode\" rel=\"noopener noreferrer\" target=\"_blank\">Dark Mode for iOS 13 Preview<\/a><\/p>\n<h2>Xamarin.Forms<\/h2>\n<p>All of the above applies to Xamarin.Forms as well! We know many of you prefer to share as much code as possible, and that includes styles. The Xamarin.Forms team has <a href=\"https:\/\/github.com\/xamarin\/Xamarin.Forms\/issues\/7304\" rel=\"noopener noreferrer\" target=\"_blank\">drafted a proposal<\/a> for how we might surface appearance mode support and semantic colors. Be sure to review that and add your comments. <\/p>\n<p>Let&#8217;s take a look at how difficult it is to support Dark Mode in Xamarin.Forms today. (HINT: it&#8217;s really easy <a href=\"https:\/\/twitter.com\/shanselman\/status\/1165356640142422016\" rel=\"noopener noreferrer\" target=\"_blank\">\ud83d\ude09<\/a> )<\/p>\n<p>In this sample app, <a href=\"https:\/\/github.com\/davidortinau\/Xappy\/\" target=\"_blank\" rel=\"noopener noreferrer\">Xappy<\/a>, there are <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/xaml\/resource-dictionaries\">resource dictionaries<\/a> for dark and light themes. Each theme builds upon the base of shared styles for the application.<\/p>\n<pre class=\"lang:xhtml decode:true\" title=\"DarkTheme\">&lt;ResourceDictionary xmlns=\"http:\/\/xamarin.com\/schemas\/2014\/forms\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n             x:Class=\"Xappy.Styles.DarkTheme\"\r\n             Source=\"DefaultTheme.xaml\"&gt;\r\n\r\n    &lt;Color x:Key=\"backgroundColor\"&gt;#FF000000&lt;\/Color&gt;\r\n    \r\n    &lt;Color x:Key=\"TextPrimaryColor\"&gt;#B0FFFFFF&lt;\/Color&gt;\r\n    &lt;Color x:Key=\"TextSecondaryColor\"&gt;#B0FFFFFF&lt;\/Color&gt;\r\n    &lt;Color x:Key=\"TextTernaryColor\"&gt;#C8C8C8&lt;\/Color&gt;\r\n&lt;\/ResourceDictionary&gt;<\/pre>\n<pre class=\"lang:xhtml decode:true\" title=\"LightTheme\">&lt;ResourceDictionary xmlns=\"http:\/\/xamarin.com\/schemas\/2014\/forms\"\r\n             xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml\"\r\n             x:Class=\"Xappy.Styles.WhiteTheme\"\r\n             Source=\"DefaultTheme.xaml\"&gt;\r\n\r\n    &lt;Color x:Key=\"backgroundColor\"&gt;#FFFFFFFF&lt;\/Color&gt;\r\n\r\n    &lt;Color x:Key=\"TextPrimaryColor\"&gt;#B0000000&lt;\/Color&gt;\r\n    &lt;Color x:Key=\"TextSecondaryColor\"&gt;#80000000&lt;\/Color&gt;\r\n    &lt;Color x:Key=\"TextTernaryColor\"&gt;#C8C8C8&lt;\/Color&gt;\r\n&lt;\/ResourceDictionary&gt;<\/pre>\n<p>To make sure the colors update when the styles are changed, you&#8217;ll want to use the <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/xamarin-forms\/user-interface\/styles\/xaml\/dynamic\"><span class=\"lang:default decode:true  crayon-inline\">DynamicResource<\/span><\/a>\u00a0\u00a0markup extension. If no updates or changes are needed, use the <span class=\"lang:default decode:true  crayon-inline \">StaticResource<\/span>\u00a0markup extension.<\/p>\n<pre class=\"lang:c# decode:true\">Shell.BackgroundColor=\"{DynamicResource backgroundColor}\"\r\nBackgroundColor=\"{DynamicResource backgroundColor}\"\r\nShell.TitleColor=\"{StaticResource cerulean}\"\r\n<\/pre>\n<p>Since we are using cross-platform styling here, we need to manage iOS changes in appearance mode. This is easily done in a page renderer by listening to the <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uitraitcollection\">UITraitCollection<\/a> change. This is the <a href=\"https:\/\/github.com\/davidortinau\/Xappy\/blob\/feature\/dark13\/Xappy\/Xappy.iOS\/Renderers\/PageRenderer.cs\">PageRenderer<\/a> added to the Xappy.iOS project:<\/p>\n<pre class=\"lang:c# decode:true\">using System;\r\nusing UIKit;\r\nusing Xamarin.Forms;\r\nusing Xamarin.Forms.Platform.iOS;\r\nusing Xappy.Styles;\r\n\r\n[assembly: ExportRenderer(typeof(ContentPage), typeof(Xappy.iOS.Renderers.PageRenderer))]\r\nnamespace Xappy.iOS.Renderers\r\n{\r\n    public class PageRenderer : Xamarin.Forms.Platform.iOS.PageRenderer\r\n    {\r\n        protected override void OnElementChanged(VisualElementChangedEventArgs e)\r\n        {\r\n            base.OnElementChanged(e);\r\n\r\n            if (e.OldElement != null || Element == null)\r\n            {\r\n                return;\r\n            }\r\n\r\n            try\r\n            {\r\n                SetAppTheme();\r\n            }\r\n            catch (Exception ex)\r\n            {\r\n                System.Diagnostics.Debug.WriteLine($\"\\t\\t\\tERROR: {ex.Message}\");\r\n            }\r\n        }\r\n\r\n        public override void TraitCollectionDidChange(UITraitCollection previousTraitCollection)\r\n        {\r\n            base.TraitCollectionDidChange(previousTraitCollection);\r\n            Console.WriteLine($\"TraitCollectionDidChange: {TraitCollection.UserInterfaceStyle} != {previousTraitCollection.UserInterfaceStyle}\");\r\n\r\n            if(this.TraitCollection.UserInterfaceStyle != previousTraitCollection.UserInterfaceStyle)\r\n            {\r\n                SetAppTheme();\r\n            }\r\n\r\n            \r\n        }\r\n\r\n        void SetAppTheme()\r\n        {\r\n            if (this.TraitCollection.UserInterfaceStyle == UIUserInterfaceStyle.Dark)\r\n            {\r\n                if (App.AppTheme == \"dark\")\r\n                    return;\r\n                \r\n                App.Current.Resources = new DarkTheme();\r\n\r\n                App.AppTheme = \"dark\";\r\n            }\r\n            else\r\n            {\r\n                if (App.AppTheme != \"dark\")\r\n                    return;\r\n                App.Current.Resources = new WhiteTheme();\r\n                App.AppTheme = \"light\";\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>This code applies the current theme if it has changed when the view is displayed. This makes sure the app starts in the right mode. Then any time iOS notifies the app that traits have changed, such as <a href=\"https:\/\/developer.apple.com\/documentation\/uikit\/uiuserinterfacestyle\">UIUserInterfaceStyle<\/a>, the code checks that the change is different than the styles currently being displayed as tracked by AppTheme, a simple variable for tracking this.<\/p>\n<p>In the future, Xamarin.Forms will support this more directly (<a href=\"https:\/\/github.com\/xamarin\/Xamarin.Forms\/issues\/7304\" rel=\"noopener noreferrer\" target=\"_blank\">read the proposal<\/a>), but as you can see it&#8217;s very little code to update your existing Xamarin.Forms code to adopt these new features of iOS 13.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-45183\" src=\"http:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_Forms.png\" alt=\"Xamarin.Forms Dark Mode\" width=\"600\" height=\"537\" srcset=\"https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_Forms.png 782w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_Forms-300x269.png 300w, https:\/\/devblogs.microsoft.com\/xamarin\/wp-content\/uploads\/sites\/44\/2019\/08\/LightAndDark_Forms-768x687.png 768w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Xappy on GitHub: <a href=\"https:\/\/github.com\/davidortinau\/Xappy\/tree\/feature\/dark13\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/davidortinau\/Xappy\/tree\/feature\/dark13\/<\/a><\/p>\n<h2>Get Started with iOS 13 Preview<\/h2>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/xamarin\/ios-13-xcode-11\/\" target=\"_blank\" rel=\"noopener noreferrer\">Since early July<\/a> we have been shipping updates as Apple releases new Xcode 11 betas. The Xcode beta can be installed side-by-side with a stable version of Xcode. You can always return to the stable release channel in order to use your original production environment.<\/p>\n<p>Important note: this preview requires a Mac running macOS 10.14.4 (Mojave) or newer! macOS 10.15 (Catalina) is supported in this release. Although you may need to take <a href=\"https:\/\/github.com\/xamarin\/xamarin-macios\/issues\/6452\" target=\"_blank\" rel=\"noopener noreferrer\">additional steps<\/a> to install the preview.<\/p>\n<h3>Installation<\/h3>\n<p>To get started:<\/p>\n<ol>\n<li>Download and install the Xcode 11 beta from the <a href=\"https:\/\/developer.apple.com\/download\/\" target=\"_blank\" rel=\"noopener noreferrer\">Apple Developer Portal<\/a>.<\/li>\n<li>In Visual Studio for Mac, select Visual Studio &gt; Check for Updates, select the Xcode 11 Previews channel, and install the available updates.<\/li>\n<li>In Visual Studio for Mac, select Visual Studio &gt; Preferences &gt; Projects &gt; SDK Locations &gt; Apple and select Xcode-beta.app.<\/li>\n<li>(Optional \u2013 Visual Studio 2019 only) Download and install the <a href=\"https:\/\/download.visualstudio.microsoft.com\/download\/pr\/b100c387-4a89-42a3-ab7d-a6cd04af5827\/4cf76ce476c1f03619b4929fcfd5c6d6\/xamarin.visualstudio.alpha.16.2.0.3013215-51445dd.vsix\" target=\"_blank\" rel=\"noopener noreferrer\">Xcode 11 preview support VSIX<\/a>.<\/li>\n<\/ol>\n<p>That\u2019s it! Begin building your apps against Xcode 11 and utilize the available iOS 13 APIs within your Xamarin apps. Detailed instructions can be found on the <a href=\"https:\/\/docs.microsoft.com\/xamarin\/ios\/platform\/ios13\/get-started\" target=\"_blank\" rel=\"noopener noreferrer\">Xamarin Documentation Portal<\/a>.<\/p>\n<p><b>Update (September 4th)<\/b>: Preview 6 of our support for Xcode 11 and iOS 13 is now available. Huge thanks for community contribution to AVKit. Read our <a href=\"https:\/\/docs.microsoft.com\/en-us\/xamarin\/ios\/release-notes\/12\/12.99#september-4-2019\" target=\"_blank\" rel=\"noopener noreferrer\">release notes<\/a> for more information, and <a href=\"https:\/\/forums.xamarin.com\/discussion\/162764\/preview-xamarin-ios-preview-3-for-xcode-11-and-ios-13\/p1?new=1\">visit the forums to discuss<\/a>.<\/p>\n<h3>Share Your Experience<\/h3>\n<p>We want to hear how our Xcode 11 preview support works for you! Build your application against Xcode 11 using today\u2019s preview to ensure that your app(s) continues to build using this preview. After, start integrating new APIs such as Sign in with Apple in your app(s). Our priorities are driven by your feedback. Let us know which features from Xcode 11 and iOS 13 are important to you. <a href=\"https:\/\/www.surveymonkey.com\/r\/R5X6DJR\" target=\"_blank\" rel=\"noopener noreferrer\">Complete our survey<\/a>.<\/p>\n<p>Please <a href=\"https:\/\/github.com\/xamarin\/xamarin-macios\/issues\/new\" target=\"_blank\" rel=\"noopener noreferrer\">log an issue<\/a> on GitHub with any feedback.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Xamarin.iOS and Xamarin.Forms deliver native iOS experiences for iOS 13 Apple which introduces dark mode: A system-wide option for light and dark themes to choose themes or allow iOS to dynamically change appearance based on the environment and time of day. <\/p>\n","protected":false},"author":553,"featured_media":45185,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[303,367],"tags":[6,6254,3616,16],"class_list":["post-45181","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ios","category-xamarin-forms","tag-ios","tag-ios-13","tag-macos","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>Xamarin.iOS and Xamarin.Forms deliver native iOS experiences for iOS 13 Apple which introduces dark mode: A system-wide option for light and dark themes to choose themes or allow iOS to dynamically change appearance based on the environment and time of day. <\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/45181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/553"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=45181"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/45181\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/45185"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=45181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=45181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=45181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}