Last active
June 6, 2019 17:51
-
-
Save rsaenzi/95aa565dbd263a045bcde466ff8e0ccd to your computer and use it in GitHub Desktop.
Theme controller to apply a color set over all UI views in an iOS app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // Theme.swift | |
| // | |
| // Created by Rigoberto Sáenz Imbacuán (https://www.linkedin.com/in/rsaenzi/) | |
| // Copyright © 2019. All rights reserved. | |
| // | |
| import UIKit | |
| class Theme { | |
| // Singleton | |
| static let shared = Theme() | |
| // Theme Colors | |
| var primaryColor = #colorLiteral(red: 0.992156862745098, green: 0.427450980392157, blue: 0.152941176470588, alpha: 1) | |
| var subTextColor = #colorLiteral(red: 0.494117647058824, green: 0.501960784313725, blue: 0.509803921568627, alpha: 1) | |
| // MARK: Life Cycle | |
| private init() { | |
| defer { | |
| UIView.appearance().tintColor = primaryColor | |
| UIApplication.shared.delegate?.window??.tintColor = primaryColor | |
| } | |
| // Load the file | |
| guard let path = Bundle.main.path(forResource: "Theme", ofType: "plist"), | |
| let xml = FileManager.default.contents(atPath: path), | |
| let file = try? PropertyListDecoder().decode(ThemeFile.self, from: xml) else { | |
| return | |
| } | |
| // Detect which theme must be used | |
| let selectedTheme = file.allThemes.first { item -> Bool in | |
| return item.name.lowercased() == file.activeThemeName.lowercased() | |
| } | |
| guard let validTheme = selectedTheme else { | |
| return | |
| } | |
| // Create colors using rgb values read from selected theme | |
| primaryColor = getColor(from: validTheme.primaryColor) | |
| subTextColor = getColor(from: validTheme.subTextColor) | |
| } | |
| // MARK: Internal | |
| private func getColor(from colorValues: ThemeColor) -> UIColor { | |
| return UIColor.init( | |
| red: CGFloat(colorValues.red) / 256, | |
| green: CGFloat(colorValues.green) / 256, | |
| blue: CGFloat(colorValues.blue) / 256, | |
| alpha: 1) | |
| } | |
| } | |
| private struct ThemeFile: Codable { | |
| var activeThemeName: String | |
| var allThemes: [ThemeItem] | |
| } | |
| private struct ThemeItem: Codable { | |
| var name: String | |
| var primaryColor: ThemeColor | |
| var subTextColor: ThemeColor | |
| } | |
| private struct ThemeColor: Codable { | |
| var red: Int | |
| var green: Int | |
| var blue: Int | |
| } | |
| // Goes in a Theme.plist file | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| <plist version="1.0"> | |
| <dict> | |
| <key>activeThemeName</key> | |
| <string>ThemeA</string> | |
| <key>allThemes</key> | |
| <array> | |
| <dict> | |
| <key>name</key> | |
| <string>ThemeA</string> | |
| <key>primaryColor</key> | |
| <dict> | |
| <key>red</key> | |
| <integer>255</integer> | |
| <key>green</key> | |
| <integer>0</integer> | |
| <key>blue</key> | |
| <integer>0</integer> | |
| </dict> | |
| <key>secondaryColor</key> | |
| <dict> | |
| <key>red</key> | |
| <integer>0</integer> | |
| <key>green</key> | |
| <integer>255</integer> | |
| <key>blue</key> | |
| <integer>0</integer> | |
| </dict> | |
| </dict> | |
| <dict> | |
| <key>name</key> | |
| <string>ThemeB</string> | |
| <key>primaryColor</key> | |
| <dict> | |
| <key>red</key> | |
| <integer>0</integer> | |
| <key>green</key> | |
| <integer>255</integer> | |
| <key>blue</key> | |
| <integer>255</integer> | |
| </dict> | |
| <key>secondaryColor</key> | |
| <dict> | |
| <key>red</key> | |
| <integer>0</integer> | |
| <key>green</key> | |
| <integer>0</integer> | |
| <key>blue</key> | |
| <integer>255</integer> | |
| </dict> | |
| </dict> | |
| </array> | |
| </dict> | |
| </plist> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment