JKSwiftExtension 中JKDarkModeUtil
和 JKThemeProvider
有源碼
- 目錄:
- 1咬摇、暗黑模式介紹
- 2管削、暗黑模式的關(guān)閉和打開
- 3扒秸、iOS 13 暗黑模式的適配 (
重點看
) - 4愿汰、iOS 13 以下主題的適配:淺色和深色 (
重點看
) - 5桥狡、一次適配不完的問題
一恒界、暗黑模式的介紹
-
1.1烟阐、暗黑模式的簡介
從 iOS 13.0 版本開始辣卒,用戶可以選擇采用系統(tǒng)范圍內(nèi)的淺色或深色外觀墓卦。 深色外觀(稱為暗黑模式DarkMode)實現(xiàn)了許多應(yīng)用程序已經(jīng)采用的界面樣式倦春。 用戶可以選擇自己喜歡的美學,也可以選擇根據(jù)環(huán)境照明條件或特定時間表來切換其界面落剪。
所有應(yīng)用程序都應(yīng)該支持淺色和深色界面樣式睁本,但在某些地方的特定外觀可能會表現(xiàn)更好。例如著榴,您可能總是為印刷內(nèi)容采用輕巧的外觀添履。
在更改代碼之前,請打開黑暗模式脑又,看看應(yīng)用程序的反應(yīng)暮胧。系統(tǒng)為您做了很多工作,如果您的應(yīng)用程序使用標準視圖和控件问麸,您可能不需要進行許多更改往衷。標準視圖和控件會自動更新其外觀,以匹配當前界面樣式严卖。如果您已經(jīng)使用顏色和圖像資產(chǎn)席舍,您可以在不更改代碼的情況下添加深色變體。 -
1.2哮笆、UITraitCollection介紹
在 iOS 13 中来颤,我們可以通過 UITraitCollection 來判斷當前系統(tǒng)的模式。UIView 和 UIViewController 稠肘、UIScreen福铅、UIWindow 都已經(jīng)遵從了UITraitEnvironment 這個協(xié)議,因此這些類都擁有一個叫做 traitCollection 的屬性项阴,在這些類中滑黔,我們可以這樣去判斷當前 App 的顏色模式:let isDark = self.traitCollection.userInterfaceStyle == .dark
1.3、模擬器暗黑模式切換的快捷鍵:
command+shift+A
二、暗黑模式的關(guān)閉和打開
-
2.1略荡、自己的app還沒有適配暗黑模式又擔心用戶使用暗黑模式的時候界面不好看:關(guān)閉暗黑模式
-
方式一:暫時全局關(guān)閉暗黑模式:
在Info.plist
文件中庵佣,添加 key 為UIUserInterfaceStyle
,類型為 String汛兜,value 設(shè)置為Light
即可
Info.plist關(guān)閉暗黑模式 -
方式二:使用代碼的方式
強制關(guān)閉暗黑模式if #available(iOS 13.0,*) { UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = .light }
-
-
2.2巴粪、單個頁面關(guān)閉暗黑模式
self.overrideUserInterfaceStyle = .light
提示:設(shè)置此屬性會影響當前
view/viewController/window
以及它下面的任何內(nèi)容如果你希望一個子視圖監(jiān)聽系統(tǒng)的模式,請將
overrideUserInterfaceStyle
屬性設(shè)置為unspecified
self.overrideUserInterfaceStyle = .unspecified
三粥谬、iOS 13 暗黑模式的適配
-
3.1验毡、iOS 13的暗黑模式我們主要分為:
跟隨系統(tǒng)模式
和自定義模式
-
跟隨系統(tǒng),需要設(shè)置:
UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = .unspecified
不跟隨系統(tǒng)
淺色:UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = .light
深色:UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = .dark
-
-
3.2帝嗡、iOS 13的暗黑模式適配代碼在:
JKDarkModeUtil
里面晶通,默認是跟隨系統(tǒng)模式
,主要代碼如下import UIKit public class JKDarkModeUtil { /// 跟隨系統(tǒng)的key private static let JKDarkToSystem = "JKDarkToSystem" /// 是否淺色模式的key private static let JKLightDark = "JKLightDark" /// 是否淺色 public static var isLight: Bool { if let value = UserDefaults.jk.userDefaultsGetValue(key: JKLightDark) as? Bool { return value } return true } /// 是否跟隨系統(tǒng) public static var isFloorSystem: Bool { if #available(iOS 13, *) { if let value = UserDefaults.jk.userDefaultsGetValue(key: JKDarkToSystem) as? Bool { return value } return true } return false } } // MARK:- 方法的調(diào)用 extension JKDarkModeUtil: JKThemeable { public func apply() {} } public extension JKDarkModeUtil { // MARK: 初始化的調(diào)用 /// 默認設(shè)置 static func defaultDark() { if #available(iOS 13.0, *) { // 默認跟隨系統(tǒng)暗黑模式開啟監(jiān)聽 if (JKDarkModeUtil.isFloorSystem) { JKDarkModeUtil.setDarkModeFollowSystem(isFollowSystem: true) } else { UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = JKDarkModeUtil.isLight ? .light : .dark } } } // MARK: 設(shè)置系統(tǒng)是否跟隨 static func setDarkModeFollowSystem(isFollowSystem: Bool) { if #available(iOS 13.0, *) { // 1.1哟玷、設(shè)置是否跟隨系統(tǒng) UserDefaults.jk.userDefaultsSetValue(value: isFollowSystem, key: JKDarkToSystem) let result = UITraitCollection.current.userInterfaceStyle == .light ? true : false UserDefaults.jk.userDefaultsSetValue(value: result, key: JKLightDark) // 1.2狮辽、設(shè)置模式的保存 if isFollowSystem { UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = .unspecified } else { UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = UITraitCollection.current.userInterfaceStyle } } } // MARK: 設(shè)置:淺色 / 深色 static func setDarkModeCustom(isLight: Bool) { if #available(iOS 13.0, *) { // 1.1、只要設(shè)置了模式:就是黑或者白 UIApplication.shared.windows.filter({$0.isKeyWindow}).first?.overrideUserInterfaceStyle = isLight ? .light : .dark // 1.2巢寡、設(shè)置跟隨系統(tǒng):否 UserDefaults.jk.userDefaultsSetValue(value: false, key: JKDarkToSystem) UserDefaults.jk.userDefaultsSetValue(value: isLight, key: JKLightDark) } else { // 模式存儲 UserDefaults.jk.userDefaultsSetValue(value: isLight, key: JKLightDark) // 通知模式更新 LegacyThemeProvider.shared.updateTheme() } } } // MARK:- 動態(tài)顏色的使用 public extension JKDarkModeUtil { static func colorLightDark(light: UIColor, dark: UIColor) -> UIColor { if #available(iOS 13.0, *) { return UIColor { (traitCollection) -> UIColor in if JKDarkModeUtil.isFloorSystem { if traitCollection.userInterfaceStyle == .light { return light } else { return dark } } else { return JKDarkModeUtil.isLight ? light : dark } } } else { // iOS 13 以下主題色的使用 if JKDarkModeUtil.isLight { return light } return dark } } } // MARK:- 動態(tài)圖片的使用 public extension JKDarkModeUtil { // MARK: 深色圖片和淺色圖片切換 (深色模式適配) /// 深色圖片和淺色圖片切換 (深色模式適配) /// - Parameters: /// - light: 淺色圖片 /// - dark: 深色圖片 /// - Returns: 最終圖片 static func image(light: UIImage?, dark: UIImage?) -> UIImage? { if #available(iOS 13.0, *) { guard let weakLight = light, let weakDark = dark, let config = weakLight.configuration else { return light } let lightImage = weakLight.withConfiguration(config.withTraitCollection(UITraitCollection.init(userInterfaceStyle: UIUserInterfaceStyle.light))) lightImage.imageAsset?.register(weakDark, with: config.withTraitCollection(UITraitCollection(userInterfaceStyle: UIUserInterfaceStyle.dark))) return lightImage.imageAsset?.image(with: UITraitCollection.current) ?? light } else { // iOS 13 以下主題色的使用 if JKDarkModeUtil.isLight { return light } return dark } } }
-
3.3喉脖、UIColor 顏色的使用方式
JKDarkModeUtil.colorLightDark(light: UIColor.yellow, dark: UIColor.green)
提示:建議自定義業(yè)務(wù)色,如下
// MARK:- 業(yè)務(wù)顏色的使用 extension UIColor { /// 背景色 private(set) static var cA1 = JKDarkModeUtil.colorLightDark(light: UIColor.yellow, dark: UIColor.green) }
使用:
self.view.backgroundColor = .cA1
-
3.4抑月、CGColor 適配树叽,實現(xiàn)
traitCollectionDidChange
方法,適配顏色即可override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) // cgColor 顏色適配 button.layer.borderColor = JKDarkModeUtil.colorLightDark(light: .green, dark: .brown).cgColor }
提示: 完整的觸發(fā)方法文檔
-
3.5谦絮、暗黑模式圖片的使用(選擇:Any,Dark)
-
Assets中添加圖片
暗黑模式圖片的使用 -
代碼適配圖片
// MARK:- 動態(tài)圖片的使用(網(wǎng)絡(luò)圖片一樣) public extension JKDarkModeUtil { // MARK: 深色圖片和淺色圖片切換 (深色模式適配) /// 深色圖片和淺色圖片切換 (深色模式適配) /// - Parameters: /// - light: 淺色圖片 /// - dark: 深色圖片 /// - Returns: 最終圖片 static func image(light: UIImage?, dark: UIImage?) -> UIImage? { if #available(iOS 13.0, *) { guard let weakLight = light, let weakDark = dark, let config = weakLight.configuration else { return light } let lightImage = weakLight.withConfiguration(config.withTraitCollection(UITraitCollection.init(userInterfaceStyle: UIUserInterfaceStyle.light))) lightImage.imageAsset?.register(weakDark, with: config.withTraitCollection(UITraitCollection(userInterfaceStyle: UIUserInterfaceStyle.dark))) return lightImage.imageAsset?.image(with: UITraitCollection.current) ?? light } else { // iOS 13 以下主題色的使用 if JKDarkModeUtil.isLight { return light } return dark } } }
- 提示:代碼適配的時候需要在:
traitCollectionDidChange
方法里面再次賦值题诵,iOS 13
以上的建議直接再 Assets中添加圖片
如果是cell
里面的圖直接使用方法加載圖片,刷新一下視圖即可
- 提示:代碼適配的時候需要在:
-
四层皱、iOS 13 以下主題的適配:淺色和深色
-
4.1性锭、iOS 13 以下我們采用的是
監(jiān)聽模式
來改變主題色,源碼在JKThemeProvider
叫胖,使用步驟如下-
1>草冈、遵守協(xié)議
JKThemeable
(遵守UITraitEnvironment
協(xié)議的均可使用)extension ViewController: JKThemeable { func apply() { self.view.backgroundColor = JKDarkModeUtil.colorLightDark(light: UIColor.yellow, dark: UIColor.green) } }
-
2>、注冊監(jiān)聽模式變化
themeProvider.register(observer: self)
-
3>瓮增、模式變化通知
JKDarkModeUtil.setDarkModeCustom(isLight: true)
-
-
4.2怎棱、顏色的調(diào)用和圖片模式的調(diào)用和iOS13一樣
-
顏色調(diào)用
JKDarkModeUtil.colorLightDark(light: UIColor.yellow, dark: UIColor.green)
-
圖片調(diào)用
JKDarkModeUtil.image(light: UIImage(named: "tabbar_profile"), dark: UIImage(named: "tabbar_profile_selected"))
-
-
4.3、主題變化后會走代理
apply()
绷跑,在代理方法里面我們只需要重新調(diào)用顏色或者圖片的方法即可extension ViewController: JKThemeable { func apply() { self.view.backgroundColor = JKDarkModeUtil.colorLightDark(light: UIColor.yellow, dark: UIColor.green) darkImageView.image = JKDarkModeUtil.image(light: UIImage(named: "tabbar_profile"), dark: UIImage(named: "tabbar_profile_selected")) } }
五拳恋、一次適配不完的問題
- 5.1、一次適配不完的問題你踩,我們在使用JKDarkModeUtil 調(diào)用一些方法的時候诅岩,適配哪里就哪里使用即可,不使用的就按照之前的顏色以及圖片調(diào)用即可
- 5.2带膜、提示:在使用
JKDarkModeUtil
和JKThemeProvider
的時候吩谦,需要在設(shè)置window
的rootViewController
后需要調(diào)用JKDarkModeUtil.defaultDark()