How to change color theme of the app according to the conditions?












2















I'm trying to find the best approach about changing color theme of an app. After my investigations I inspired Durul Dalkanat's post on https://medium.com/@duruldalkanat/part-2-installing-theme-manager-18a32c314cf1 and wrote below codes in order to apply to my app.



My problem is that the color theme doesn't change when user switch the switch button.



If necessary to explain in a detailed manner



I created an enumeration that includes my colors.



enum ColorTheme: Int {
case day, night

var mainColor:UIColor {
switch self {
case .day:
return UIColor().hexToUIColor("D9D8C8")
case .night:
return UIColor().hexToUIColor("141B1B")

}
}}


And then I created a struct in order to apply my color theme to all components in my app and set to user defaults and get from there like below.



let selectedThemeKey = "SelectedTheme"

struct ThemeManager {

static func currentTheme() -> ColorTheme {

if let storedTheme = (UserDefaults.standard.value(forKey: selectedThemeKey) as AnyObject).integerValue {
return ColorTheme(rawValue: storedTheme)!
} else {
return .night
}
}

static func applyTheme(theme:ColorTheme){

UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
UserDefaults.standard.synchronize()

UITabBar.appearance().backgroundColor = currentTheme().mainColor
}}


And then I added my code to
didFinishLaunchWithOptions method in AppDelegate



let defaultTheme = ThemeManager.currentTheme()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

let defaultTheme = ThemeManager.currentTheme()
ThemeManager.applyTheme(theme: defaultTheme)
return true

}


Finally I added a UISwitch to my SettingViewController to change my color theme and I want to manage my color theme with in its action as below.



let appDelegate = UIApplication.shared.delegate as! AppDelegate

@IBAction func colorModeSwitchSwiped(_ sender: UISwitch) {


if colorModeSwitch.isOn {
ThemeManager.applyTheme(theme: ColorTheme.day)

}else {
ThemeManager.applyTheme(theme: ColorTheme.night)

}

}


This codes works in ViewController to change view background color when I switch but the application must be restarted for the UITabBar color to change. Colors doesn't change at the same time like I defined in ViewControllers. ViewController Example;



override func viewWillAppear(_ animated: Bool) {
self.view.backgroundColor = ThemeManager.currentTheme().mainColor
}


How can solve this problem? What is the correct approach?










share|improve this question

























  • Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

    – Prashant
    Nov 20 '18 at 12:49











  • If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

    – Kamran
    Nov 20 '18 at 12:54


















2















I'm trying to find the best approach about changing color theme of an app. After my investigations I inspired Durul Dalkanat's post on https://medium.com/@duruldalkanat/part-2-installing-theme-manager-18a32c314cf1 and wrote below codes in order to apply to my app.



My problem is that the color theme doesn't change when user switch the switch button.



If necessary to explain in a detailed manner



I created an enumeration that includes my colors.



enum ColorTheme: Int {
case day, night

var mainColor:UIColor {
switch self {
case .day:
return UIColor().hexToUIColor("D9D8C8")
case .night:
return UIColor().hexToUIColor("141B1B")

}
}}


And then I created a struct in order to apply my color theme to all components in my app and set to user defaults and get from there like below.



let selectedThemeKey = "SelectedTheme"

struct ThemeManager {

static func currentTheme() -> ColorTheme {

if let storedTheme = (UserDefaults.standard.value(forKey: selectedThemeKey) as AnyObject).integerValue {
return ColorTheme(rawValue: storedTheme)!
} else {
return .night
}
}

static func applyTheme(theme:ColorTheme){

UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
UserDefaults.standard.synchronize()

UITabBar.appearance().backgroundColor = currentTheme().mainColor
}}


And then I added my code to
didFinishLaunchWithOptions method in AppDelegate



let defaultTheme = ThemeManager.currentTheme()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

let defaultTheme = ThemeManager.currentTheme()
ThemeManager.applyTheme(theme: defaultTheme)
return true

}


Finally I added a UISwitch to my SettingViewController to change my color theme and I want to manage my color theme with in its action as below.



let appDelegate = UIApplication.shared.delegate as! AppDelegate

@IBAction func colorModeSwitchSwiped(_ sender: UISwitch) {


if colorModeSwitch.isOn {
ThemeManager.applyTheme(theme: ColorTheme.day)

}else {
ThemeManager.applyTheme(theme: ColorTheme.night)

}

}


This codes works in ViewController to change view background color when I switch but the application must be restarted for the UITabBar color to change. Colors doesn't change at the same time like I defined in ViewControllers. ViewController Example;



override func viewWillAppear(_ animated: Bool) {
self.view.backgroundColor = ThemeManager.currentTheme().mainColor
}


How can solve this problem? What is the correct approach?










share|improve this question

























  • Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

    – Prashant
    Nov 20 '18 at 12:49











  • If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

    – Kamran
    Nov 20 '18 at 12:54
















2












2








2








I'm trying to find the best approach about changing color theme of an app. After my investigations I inspired Durul Dalkanat's post on https://medium.com/@duruldalkanat/part-2-installing-theme-manager-18a32c314cf1 and wrote below codes in order to apply to my app.



My problem is that the color theme doesn't change when user switch the switch button.



If necessary to explain in a detailed manner



I created an enumeration that includes my colors.



enum ColorTheme: Int {
case day, night

var mainColor:UIColor {
switch self {
case .day:
return UIColor().hexToUIColor("D9D8C8")
case .night:
return UIColor().hexToUIColor("141B1B")

}
}}


And then I created a struct in order to apply my color theme to all components in my app and set to user defaults and get from there like below.



let selectedThemeKey = "SelectedTheme"

struct ThemeManager {

static func currentTheme() -> ColorTheme {

if let storedTheme = (UserDefaults.standard.value(forKey: selectedThemeKey) as AnyObject).integerValue {
return ColorTheme(rawValue: storedTheme)!
} else {
return .night
}
}

static func applyTheme(theme:ColorTheme){

UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
UserDefaults.standard.synchronize()

UITabBar.appearance().backgroundColor = currentTheme().mainColor
}}


And then I added my code to
didFinishLaunchWithOptions method in AppDelegate



let defaultTheme = ThemeManager.currentTheme()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

let defaultTheme = ThemeManager.currentTheme()
ThemeManager.applyTheme(theme: defaultTheme)
return true

}


Finally I added a UISwitch to my SettingViewController to change my color theme and I want to manage my color theme with in its action as below.



let appDelegate = UIApplication.shared.delegate as! AppDelegate

@IBAction func colorModeSwitchSwiped(_ sender: UISwitch) {


if colorModeSwitch.isOn {
ThemeManager.applyTheme(theme: ColorTheme.day)

}else {
ThemeManager.applyTheme(theme: ColorTheme.night)

}

}


This codes works in ViewController to change view background color when I switch but the application must be restarted for the UITabBar color to change. Colors doesn't change at the same time like I defined in ViewControllers. ViewController Example;



override func viewWillAppear(_ animated: Bool) {
self.view.backgroundColor = ThemeManager.currentTheme().mainColor
}


How can solve this problem? What is the correct approach?










share|improve this question
















I'm trying to find the best approach about changing color theme of an app. After my investigations I inspired Durul Dalkanat's post on https://medium.com/@duruldalkanat/part-2-installing-theme-manager-18a32c314cf1 and wrote below codes in order to apply to my app.



My problem is that the color theme doesn't change when user switch the switch button.



If necessary to explain in a detailed manner



I created an enumeration that includes my colors.



enum ColorTheme: Int {
case day, night

var mainColor:UIColor {
switch self {
case .day:
return UIColor().hexToUIColor("D9D8C8")
case .night:
return UIColor().hexToUIColor("141B1B")

}
}}


And then I created a struct in order to apply my color theme to all components in my app and set to user defaults and get from there like below.



let selectedThemeKey = "SelectedTheme"

struct ThemeManager {

static func currentTheme() -> ColorTheme {

if let storedTheme = (UserDefaults.standard.value(forKey: selectedThemeKey) as AnyObject).integerValue {
return ColorTheme(rawValue: storedTheme)!
} else {
return .night
}
}

static func applyTheme(theme:ColorTheme){

UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
UserDefaults.standard.synchronize()

UITabBar.appearance().backgroundColor = currentTheme().mainColor
}}


And then I added my code to
didFinishLaunchWithOptions method in AppDelegate



let defaultTheme = ThemeManager.currentTheme()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

let defaultTheme = ThemeManager.currentTheme()
ThemeManager.applyTheme(theme: defaultTheme)
return true

}


Finally I added a UISwitch to my SettingViewController to change my color theme and I want to manage my color theme with in its action as below.



let appDelegate = UIApplication.shared.delegate as! AppDelegate

@IBAction func colorModeSwitchSwiped(_ sender: UISwitch) {


if colorModeSwitch.isOn {
ThemeManager.applyTheme(theme: ColorTheme.day)

}else {
ThemeManager.applyTheme(theme: ColorTheme.night)

}

}


This codes works in ViewController to change view background color when I switch but the application must be restarted for the UITabBar color to change. Colors doesn't change at the same time like I defined in ViewControllers. ViewController Example;



override func viewWillAppear(_ animated: Bool) {
self.view.backgroundColor = ThemeManager.currentTheme().mainColor
}


How can solve this problem? What is the correct approach?







ios swift






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 15 '18 at 12:51









Panda

6,31462844




6,31462844










asked Nov 20 '18 at 12:44









Ismail CaferogluIsmail Caferoglu

187




187













  • Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

    – Prashant
    Nov 20 '18 at 12:49











  • If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

    – Kamran
    Nov 20 '18 at 12:54





















  • Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

    – Prashant
    Nov 20 '18 at 12:49











  • If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

    – Kamran
    Nov 20 '18 at 12:54



















Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

– Prashant
Nov 20 '18 at 12:49





Hope this tutorial helps you: raywenderlich.com/156-chameleon-on-ios-getting-started

– Prashant
Nov 20 '18 at 12:49













If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

– Kamran
Nov 20 '18 at 12:54







If there is only one place to change the theme color then you can change view's color manually in the callback where you are changing the theme(e.g inside colorModeSwitchSwiped) for that ViewController.

– Kamran
Nov 20 '18 at 12:54














2 Answers
2






active

oldest

votes


















1














Take a look at the documentation of UIAppearance, there is a note that says:




iOS applies appearance changes when a view enters a window, it doesn’t
change the appearance of a view that’s already in a window. To change
the appearance of a view that’s currently in a window, remove the view
from the view hierarchy and then put it back.




So your tab bar color will not get changed if you set it through its appearance proxy because it's already in the view hierarchy. You need to set it directly:



tabBar.tintColor = ThemeManager.currentTheme().mainColor





share|improve this answer

































    0














    Don't use UITabBar.appearance() without didFinishLaunchingWithOptions.
    You check to the app has tabBarController, then change this tabBarController.tabBar color.



    static func applyTheme(theme:ColorTheme){

    UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
    UserDefaults.standard.synchronize()
    guard let tabBar = tabBarController?.tabBar else { return }
    tabBar.barTintColor = currentTheme().mainColor }
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393277%2fhow-to-change-color-theme-of-the-app-according-to-the-conditions%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Take a look at the documentation of UIAppearance, there is a note that says:




      iOS applies appearance changes when a view enters a window, it doesn’t
      change the appearance of a view that’s already in a window. To change
      the appearance of a view that’s currently in a window, remove the view
      from the view hierarchy and then put it back.




      So your tab bar color will not get changed if you set it through its appearance proxy because it's already in the view hierarchy. You need to set it directly:



      tabBar.tintColor = ThemeManager.currentTheme().mainColor





      share|improve this answer






























        1














        Take a look at the documentation of UIAppearance, there is a note that says:




        iOS applies appearance changes when a view enters a window, it doesn’t
        change the appearance of a view that’s already in a window. To change
        the appearance of a view that’s currently in a window, remove the view
        from the view hierarchy and then put it back.




        So your tab bar color will not get changed if you set it through its appearance proxy because it's already in the view hierarchy. You need to set it directly:



        tabBar.tintColor = ThemeManager.currentTheme().mainColor





        share|improve this answer




























          1












          1








          1







          Take a look at the documentation of UIAppearance, there is a note that says:




          iOS applies appearance changes when a view enters a window, it doesn’t
          change the appearance of a view that’s already in a window. To change
          the appearance of a view that’s currently in a window, remove the view
          from the view hierarchy and then put it back.




          So your tab bar color will not get changed if you set it through its appearance proxy because it's already in the view hierarchy. You need to set it directly:



          tabBar.tintColor = ThemeManager.currentTheme().mainColor





          share|improve this answer















          Take a look at the documentation of UIAppearance, there is a note that says:




          iOS applies appearance changes when a view enters a window, it doesn’t
          change the appearance of a view that’s already in a window. To change
          the appearance of a view that’s currently in a window, remove the view
          from the view hierarchy and then put it back.




          So your tab bar color will not get changed if you set it through its appearance proxy because it's already in the view hierarchy. You need to set it directly:



          tabBar.tintColor = ThemeManager.currentTheme().mainColor






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 20 '18 at 12:57

























          answered Nov 20 '18 at 12:51









          Mo Abdul-HameedMo Abdul-Hameed

          3,91621527




          3,91621527

























              0














              Don't use UITabBar.appearance() without didFinishLaunchingWithOptions.
              You check to the app has tabBarController, then change this tabBarController.tabBar color.



              static func applyTheme(theme:ColorTheme){

              UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
              UserDefaults.standard.synchronize()
              guard let tabBar = tabBarController?.tabBar else { return }
              tabBar.barTintColor = currentTheme().mainColor }
              }





              share|improve this answer




























                0














                Don't use UITabBar.appearance() without didFinishLaunchingWithOptions.
                You check to the app has tabBarController, then change this tabBarController.tabBar color.



                static func applyTheme(theme:ColorTheme){

                UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
                UserDefaults.standard.synchronize()
                guard let tabBar = tabBarController?.tabBar else { return }
                tabBar.barTintColor = currentTheme().mainColor }
                }





                share|improve this answer


























                  0












                  0








                  0







                  Don't use UITabBar.appearance() without didFinishLaunchingWithOptions.
                  You check to the app has tabBarController, then change this tabBarController.tabBar color.



                  static func applyTheme(theme:ColorTheme){

                  UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
                  UserDefaults.standard.synchronize()
                  guard let tabBar = tabBarController?.tabBar else { return }
                  tabBar.barTintColor = currentTheme().mainColor }
                  }





                  share|improve this answer













                  Don't use UITabBar.appearance() without didFinishLaunchingWithOptions.
                  You check to the app has tabBarController, then change this tabBarController.tabBar color.



                  static func applyTheme(theme:ColorTheme){

                  UserDefaults.standard.set(theme.rawValue, forKey: selectedThemeKey)
                  UserDefaults.standard.synchronize()
                  guard let tabBar = tabBarController?.tabBar else { return }
                  tabBar.barTintColor = currentTheme().mainColor }
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 '18 at 13:27









                  Emre ÖzdilEmre Özdil

                  26149




                  26149






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393277%2fhow-to-change-color-theme-of-the-app-according-to-the-conditions%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Academy of Television Arts & Sciences

                      L'Équipe

                      1995 France bombings