尝试重新加载视图控制器以更新当前主题
Trying to reload view controller to update the current theme
我在找什么
我正在尝试重新加载我的视图控制器中的所有视图,以在主题之间切换(类似于 Twitter
或 Apple Maps
所做的)。
我如何设置不同的主题
我的主题视图设置如下:
@IBDesignable
extension UIView {
@IBInspectable
var lightBackgroundColor: UIColor? {
set {
switch GEUserSettings.theme {
case .light: backgroundColor = newValue
case .dark: break
}
}
get {
return self.lightBackgroundColor
}
}
@IBInspectable
var darkBackgroundColor: UIColor? {
set {
switch GEUserSettings.theme {
case .light: break
case .dark: backgroundColor = newValue
}
}
get {
return self.darkBackgroundColor
}
}
}
这允许我在 Main.storyboard
中设置 light
和 dark
主题背景颜色,具体取决于当前主题。我的背景模糊效果被排除在外,因为我找不到在代码中更新 style
的方法,所以它是在 viewDidLoad
.
中创建的
摇动设备触发主题
但是,当我想改变主题时,我不知道该怎么做。我想通过摇动设备来触发它,就像这样:
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
print("Shaken!")
let oppositeTheme: GEUserSettings.Theme = {
switch GEUserSettings.theme {
case .light: return .dark
case .dark: return .light
}
}()
GEUserSettings.theme = oppositeTheme
// My attempt to update the view controller to
// update the theme, which doesn't do anything.
dismiss(animated: true) {
UIApplication.shared.keyWindow?.rootViewController?.present(self, animated: true, completion: nil)
// Yes, the presenting is working, but the views don't change.
}
}
有哪些可能的解决方案?
如果应用程序退出并重新启动,设置将生效。我可以强制退出该应用程序(不使用 exit(0)
或任何算作崩溃的东西),或者在使用该应用程序时重新加载它。
我尝试关闭然后重新加载视图控制器,如上面的代码所示。我正在重新加载的那个显示在基本视图控制器的顶部。
由于我使用的是情节提要,我该如何完成这项工作?
编辑 - 添加了我的 light/dark 模式的图像以使我的问题更清楚:
typealias Style = StyleManager
//MARK: - Style
final class StyleManager {
static func selectedThem()->Int?
{
return AppUtility?.getObject(forKey: "selectedTheme") as? Int // 1 for dark Theme ...... 2 for light Theme
}
static func BoldFont()->UIFont {
return UIFont(name: FontType.bold.fontName, size: FontType.bold.fontSize)!
}
// MARK: - Style
static func setUpTheme() {
Chameleon.setGlobalThemeUsingPrimaryColor(primaryTheme(), withSecondaryColor: theme(), usingFontName: font(), andContentStyle: content())
}
// MARK: - Theme
static func SetPagerViewsColor()->UIColor
{
return secondarythemeColor
}
static func primaryTheme() -> UIColor {
setCheckMarkBackground()
if selectedThem() == 1
{
return UIColor.white
}
else
{
return OddRowColorlight
}
}
static func theme() -> UIColor {
if selectedThem() == 1
{
EvenRowColor = EvenRowColordark
OddRowColor = OddRowColorlight
primaryThemeColor=EvenRowColor
secondarythemeColor=OddRowColor
return darkGrayThemeColor
}
else
{
EvenRowColor = lightWhiteThemeColor!
OddRowColor = UIColor.white
primaryThemeColor=EvenRowColor
secondarythemeColor=OddRowColor
return lightWhiteThemeColor!
}
// return FlatWhite()
}
static func toolBarTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
}
static func tintTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
}
static func titleTextTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return UIColor.white
}
}
static func titleTheme() -> UIColor {
if selectedThem() == 1
{
return darkGrayThemeColor
}
else
{
return FlatWhite()
}
}
static func textTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
//return FlatMint()
}
static func backgroudTheme() -> UIColor {
if selectedThem() == 1
{
return .darkGray
}
else
{
return .white
}
}
}
现在在全局范围内创建一些变量
var primaryThemeColor:UIColor!
var secondarythemeColor:UIColor!
var themeColor:UIColor!
var toolBarThemeColor:UIColor!
var tintThemeColor:UIColor!
var titleTextThemeColor:UIColor!
var titleThemeColor:UIColor!
var textThemeColor:UIColor!
var backgroundThemeColor:UIColor!
var positiveThemeColor:UIColor!
var negativeThemeColor:UIColor!
var clearThemeColor:UIColor!
var setCheckMarkBackgroundColor:UIColor!
var menuSectioColor:UIColor!
var menuCellColor:UIColor!
var menuBackgroundColor:UIColor!
var menuTextTHeme:UIColor!
var themeName:String!
var btnIconColor:UIColor!
现在在 AppDelegate 中创建以下函数并在 didFinish Launch 中调用此函数
func setCurrentThemeColors()
{
themeColor = Style.theme()
toolBarThemeColor = Style.toolBarTheme()
tintThemeColor = Style.tintTheme()
titleTextThemeColor = Style.titleTextTheme()
titleThemeColor = Style.titleTheme()
textThemeColor = Style.textTheme()
backgroundThemeColor = Style.backgroudTheme()
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.setCurrentThemeColors()
return true
}
现在你已经设置好了你的主题,你只需要在你的 baseController 中创建主题更新函数并在每个 ViewController 中重写该方法将 UI 更新逻辑放在该函数中以及当设备摇动时像下面这样调用覆盖的方法
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
print("Shaken!")
updateTheme()
appDelegate.setCurrentThemeColors()
}
func setLightTheme(){
AppUtility?.saveObject(obj: 0 as AnyObject, forKey: "selectedTheme")
}
func setDarkTheme(){
AppUtility?.saveObject(obj: 1 as AnyObject, forKey: "selectedTheme")
}
func updateTheme()
{
let theme = AppUtility?.getObject(forKey: "selectedTheme") as? Int
if theme != nil
{
_ = theme == 1 ? setLightTheme() : setDarkTheme()
}
else
{
setDarkTheme()
}
appDelegate.setCurrentThemeColors()
ConfigureView()
}
func ConfigureView(){
btnDownLoadPdf.backgroundColor = .clear
btnRightSide.backgroundColor = .clear
btnRefreshPage.backgroundColor = .clear
self.View.backgroundColor = secondarythemeColor
PeriodicePastDatesPickerView.backgroundColor = secondarythemeColor
customDatePicker.backgroundColor = secondarythemeColor
UnitPicker.backgroundColor = secondarythemeColor
currencyPicker.backgroundColor = secondarythemeColor
}
注意: 您必须根据需要更新颜色它包含一些 不会 的颜色适用于您的案例
如果你打算在你的应用程序中使用主题,Apple 提供了 UIApperance
协议,可以帮助你同时更改某种控件的属性,使用它你将拥有统一的外观UI。使用方法非常简单,改变所有UILabel
背景颜色是这样的:
UILabel.apperance().backgroundColor = .lightGray
如果您想像示例代码中那样在一个地方管理所有内容,您可以创建一个包含 UI 特征的结构,检查此结构(我使用了与您相同的名称):
import UIKit
struct GEUserSettings {
enum Theme { case light, dark }
static public var theme: Theme = .light {
didSet {
guard theme != oldValue else { return }
apply()
}
}
static weak var window: UIWindow?
static public func toggleTheme() {
self.theme = theme == .light ? .dark : .light
}
static private func apply() {
setColors()
if let window = window {
window.subviews.forEach({ (view: UIView) in
view.removeFromSuperview()
window.addSubview(view)
})
}
}
static public func setColors() {
switch theme {
case .light:
UILabel.appearance().textColor = .black
UISegmentedControl.appearance().tintColor = .blue
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).backgroundColor = .clear
UITableViewHeaderFooterView.appearance().backgroundColor = .lightGray
UITableView.appearance().backgroundColor = .white
case .dark:
UILabel.appearance().textColor = .red
UISegmentedControl.appearance().tintColor = .purple
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).backgroundColor = .clear
UITableViewHeaderFooterView.appearance().backgroundColor = .black
UITableView.appearance().backgroundColor = .darkGray
}
}
}
在 AppDelegate 中,或尽快,您应该将 UIWindow
引用传递给主题管理器结构。我在 AppDelegate
didFinishLaunchingWithOptions
中做到了。这是必要的,以便立即更改颜色。
定义此结构后,您可以根据需要自定义任何 UI 控件。例如,您可以为 UILabel
定义某种背景颜色,如果它包含在 UISegmentedControl
.
中则使用不同的背景颜色
您定义的摇动事件可以像这样在主题之间切换:
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
GEUserSettings.toggleTheme()
}
如果摇动设备,屏幕将在这两者之间切换(我只更改了几个属性):
如果您想试用示例项目,请访问 Github
希望能帮到你!
我终于想通了,使用 NotificationCenter
!
GE用户设置
GEUserSettings
现在看起来如下所示:
enum GEUserSettings {
enum Theme: String {
case light
case dark
}
/// The current theme for the user.
static var theme: Theme = .dark
#warning("Store theme in UserDefaults")
/// Toggles the theme.
static func toggleTheme() {
switch GEUserSettings.theme {
case .light: theme = .dark
case .dark: theme = .light
}
NotificationCenter.default.post(name: Notification.Name("UpdateThemeNotification"), object: nil)
}
}
GEView
GEView
是我自定义的 UIView
子类。这是替代而不是我对 UIView
的扩展。它现在看起来类似于:
/// UIView subclass to allow creating corners, shadows, and borders in storyboards.
@IBDesignable
final class GEView: UIView {
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Triggers when the theme is changed
NotificationCenter.default.addObserver(self, selector: #selector(updateBackgroundColorNotification), name: Notification.Name("UpdateThemeNotification"), object: nil)
}
@objc
private func updateBackgroundColorNotification() {
updateBackgroundColor()
}
/* ... */
// MARK: - Background
@IBInspectable
var lightBackgroundColor: UIColor? {
didSet {
updateBackgroundColor()
}
}
@IBInspectable
var darkBackgroundColor: UIColor? {
didSet {
updateBackgroundColor()
}
}
/// Updates the background color depending on the theme.
private func updateBackgroundColor() {
switch GEUserSettings.theme {
case .light: backgroundColor = self.lightBackgroundColor
case .dark: backgroundColor = self.darkBackgroundColor
}
}
}
更新通过 motionBegan(_:with:)
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
super.motionBegan(motion, with: event)
// Toggles the theme and update the views
GEUserSettings.toggleTheme()
drawerViewModel.updateBlurEffect(drawerView: drawerView)
}
然后删除并重新创建模糊,如下所示:
/// Creates the blur effect behind the collection view.
func updateBlurEffect(drawerView: GEView) {
if let blurView = drawerView.subviews[0] as? UIVisualEffectView {
blurView.removeFromSuperview()
}
let blurEffect: UIBlurEffect = {
switch GEUserSettings.theme {
case .light: return UIBlurEffect(style: .light)
case .dark: return UIBlurEffect(style: .dark)
}
}()
let blurView = UIVisualEffectView(effect: blurEffect)
drawerView.addSubview(blurView)
drawerView.sendSubviewToBack(blurView)
GEConstraints.fillView(with: blurView, for: drawerView)
}
这甚至不需要退出应用程序或重新加载视图控制器,它会立即发生!
额外(动画)
如果您愿意,还可以通过更改 updateBackgroundColor()
函数来设置颜色变化的动画:
/// Updates the background color depending on the theme.
private func updateBackgroundColor() {
UIView.animate(withDuration: 0.25) {
switch GEUserSettings.theme {
case .light: self.backgroundColor = self.lightBackgroundColor
case .dark: self.backgroundColor = self.darkBackgroundColor
}
}
}
您也可以为模糊设置动画:
/// Creates the blur effect behind the collection view.
func updateBlurEffect(drawerView: GEView) {
if let blurView = drawerView.subviews[0] as? UIVisualEffectView {
UIView.animate(withDuration: 0.25, animations: {
blurView.alpha = 0
}, completion: { _ in
blurView.removeFromSuperview()
})
}
let blurEffect: UIBlurEffect = {
switch GEUserSettings.theme {
case .light: return UIBlurEffect(style: .light)
case .dark: return UIBlurEffect(style: .dark)
}
}()
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.alpha = 0
drawerView.addSubview(blurView)
drawerView.sendSubviewToBack(blurView)
GEConstraints.fillView(with: blurView, for: drawerView)
UIView.animate(withDuration: 0.25, animations: {
blurView.alpha = 1
})
}
我在找什么
我正在尝试重新加载我的视图控制器中的所有视图,以在主题之间切换(类似于 Twitter
或 Apple Maps
所做的)。
我如何设置不同的主题
我的主题视图设置如下:
@IBDesignable
extension UIView {
@IBInspectable
var lightBackgroundColor: UIColor? {
set {
switch GEUserSettings.theme {
case .light: backgroundColor = newValue
case .dark: break
}
}
get {
return self.lightBackgroundColor
}
}
@IBInspectable
var darkBackgroundColor: UIColor? {
set {
switch GEUserSettings.theme {
case .light: break
case .dark: backgroundColor = newValue
}
}
get {
return self.darkBackgroundColor
}
}
}
这允许我在 Main.storyboard
中设置 light
和 dark
主题背景颜色,具体取决于当前主题。我的背景模糊效果被排除在外,因为我找不到在代码中更新 style
的方法,所以它是在 viewDidLoad
.
摇动设备触发主题
但是,当我想改变主题时,我不知道该怎么做。我想通过摇动设备来触发它,就像这样:
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
print("Shaken!")
let oppositeTheme: GEUserSettings.Theme = {
switch GEUserSettings.theme {
case .light: return .dark
case .dark: return .light
}
}()
GEUserSettings.theme = oppositeTheme
// My attempt to update the view controller to
// update the theme, which doesn't do anything.
dismiss(animated: true) {
UIApplication.shared.keyWindow?.rootViewController?.present(self, animated: true, completion: nil)
// Yes, the presenting is working, but the views don't change.
}
}
有哪些可能的解决方案?
如果应用程序退出并重新启动,设置将生效。我可以强制退出该应用程序(不使用 exit(0)
或任何算作崩溃的东西),或者在使用该应用程序时重新加载它。
我尝试关闭然后重新加载视图控制器,如上面的代码所示。我正在重新加载的那个显示在基本视图控制器的顶部。
由于我使用的是情节提要,我该如何完成这项工作?
编辑 - 添加了我的 light/dark 模式的图像以使我的问题更清楚:
typealias Style = StyleManager
//MARK: - Style
final class StyleManager {
static func selectedThem()->Int?
{
return AppUtility?.getObject(forKey: "selectedTheme") as? Int // 1 for dark Theme ...... 2 for light Theme
}
static func BoldFont()->UIFont {
return UIFont(name: FontType.bold.fontName, size: FontType.bold.fontSize)!
}
// MARK: - Style
static func setUpTheme() {
Chameleon.setGlobalThemeUsingPrimaryColor(primaryTheme(), withSecondaryColor: theme(), usingFontName: font(), andContentStyle: content())
}
// MARK: - Theme
static func SetPagerViewsColor()->UIColor
{
return secondarythemeColor
}
static func primaryTheme() -> UIColor {
setCheckMarkBackground()
if selectedThem() == 1
{
return UIColor.white
}
else
{
return OddRowColorlight
}
}
static func theme() -> UIColor {
if selectedThem() == 1
{
EvenRowColor = EvenRowColordark
OddRowColor = OddRowColorlight
primaryThemeColor=EvenRowColor
secondarythemeColor=OddRowColor
return darkGrayThemeColor
}
else
{
EvenRowColor = lightWhiteThemeColor!
OddRowColor = UIColor.white
primaryThemeColor=EvenRowColor
secondarythemeColor=OddRowColor
return lightWhiteThemeColor!
}
// return FlatWhite()
}
static func toolBarTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
}
static func tintTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
}
static func titleTextTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return UIColor.white
}
}
static func titleTheme() -> UIColor {
if selectedThem() == 1
{
return darkGrayThemeColor
}
else
{
return FlatWhite()
}
}
static func textTheme() -> UIColor {
if selectedThem() == 1
{
return UIColor.white
}
else
{
return FlatBlack()
}
//return FlatMint()
}
static func backgroudTheme() -> UIColor {
if selectedThem() == 1
{
return .darkGray
}
else
{
return .white
}
}
}
现在在全局范围内创建一些变量
var primaryThemeColor:UIColor!
var secondarythemeColor:UIColor!
var themeColor:UIColor!
var toolBarThemeColor:UIColor!
var tintThemeColor:UIColor!
var titleTextThemeColor:UIColor!
var titleThemeColor:UIColor!
var textThemeColor:UIColor!
var backgroundThemeColor:UIColor!
var positiveThemeColor:UIColor!
var negativeThemeColor:UIColor!
var clearThemeColor:UIColor!
var setCheckMarkBackgroundColor:UIColor!
var menuSectioColor:UIColor!
var menuCellColor:UIColor!
var menuBackgroundColor:UIColor!
var menuTextTHeme:UIColor!
var themeName:String!
var btnIconColor:UIColor!
现在在 AppDelegate 中创建以下函数并在 didFinish Launch 中调用此函数
func setCurrentThemeColors()
{
themeColor = Style.theme()
toolBarThemeColor = Style.toolBarTheme()
tintThemeColor = Style.tintTheme()
titleTextThemeColor = Style.titleTextTheme()
titleThemeColor = Style.titleTheme()
textThemeColor = Style.textTheme()
backgroundThemeColor = Style.backgroudTheme()
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.setCurrentThemeColors()
return true
}
现在你已经设置好了你的主题,你只需要在你的 baseController 中创建主题更新函数并在每个 ViewController 中重写该方法将 UI 更新逻辑放在该函数中以及当设备摇动时像下面这样调用覆盖的方法
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
print("Shaken!")
updateTheme()
appDelegate.setCurrentThemeColors()
}
func setLightTheme(){
AppUtility?.saveObject(obj: 0 as AnyObject, forKey: "selectedTheme")
}
func setDarkTheme(){
AppUtility?.saveObject(obj: 1 as AnyObject, forKey: "selectedTheme")
}
func updateTheme()
{
let theme = AppUtility?.getObject(forKey: "selectedTheme") as? Int
if theme != nil
{
_ = theme == 1 ? setLightTheme() : setDarkTheme()
}
else
{
setDarkTheme()
}
appDelegate.setCurrentThemeColors()
ConfigureView()
}
func ConfigureView(){
btnDownLoadPdf.backgroundColor = .clear
btnRightSide.backgroundColor = .clear
btnRefreshPage.backgroundColor = .clear
self.View.backgroundColor = secondarythemeColor
PeriodicePastDatesPickerView.backgroundColor = secondarythemeColor
customDatePicker.backgroundColor = secondarythemeColor
UnitPicker.backgroundColor = secondarythemeColor
currencyPicker.backgroundColor = secondarythemeColor
}
注意: 您必须根据需要更新颜色它包含一些 不会 的颜色适用于您的案例
如果你打算在你的应用程序中使用主题,Apple 提供了 UIApperance
协议,可以帮助你同时更改某种控件的属性,使用它你将拥有统一的外观UI。使用方法非常简单,改变所有UILabel
背景颜色是这样的:
UILabel.apperance().backgroundColor = .lightGray
如果您想像示例代码中那样在一个地方管理所有内容,您可以创建一个包含 UI 特征的结构,检查此结构(我使用了与您相同的名称):
import UIKit
struct GEUserSettings {
enum Theme { case light, dark }
static public var theme: Theme = .light {
didSet {
guard theme != oldValue else { return }
apply()
}
}
static weak var window: UIWindow?
static public func toggleTheme() {
self.theme = theme == .light ? .dark : .light
}
static private func apply() {
setColors()
if let window = window {
window.subviews.forEach({ (view: UIView) in
view.removeFromSuperview()
window.addSubview(view)
})
}
}
static public func setColors() {
switch theme {
case .light:
UILabel.appearance().textColor = .black
UISegmentedControl.appearance().tintColor = .blue
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).backgroundColor = .clear
UITableViewHeaderFooterView.appearance().backgroundColor = .lightGray
UITableView.appearance().backgroundColor = .white
case .dark:
UILabel.appearance().textColor = .red
UISegmentedControl.appearance().tintColor = .purple
UILabel.appearance(whenContainedInInstancesOf: [UISegmentedControl.self]).backgroundColor = .clear
UITableViewHeaderFooterView.appearance().backgroundColor = .black
UITableView.appearance().backgroundColor = .darkGray
}
}
}
在 AppDelegate 中,或尽快,您应该将 UIWindow
引用传递给主题管理器结构。我在 AppDelegate
didFinishLaunchingWithOptions
中做到了。这是必要的,以便立即更改颜色。
定义此结构后,您可以根据需要自定义任何 UI 控件。例如,您可以为 UILabel
定义某种背景颜色,如果它包含在 UISegmentedControl
.
您定义的摇动事件可以像这样在主题之间切换:
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
GEUserSettings.toggleTheme()
}
如果摇动设备,屏幕将在这两者之间切换(我只更改了几个属性):
如果您想试用示例项目,请访问 Github
希望能帮到你!
我终于想通了,使用 NotificationCenter
!
GE用户设置
GEUserSettings
现在看起来如下所示:
enum GEUserSettings {
enum Theme: String {
case light
case dark
}
/// The current theme for the user.
static var theme: Theme = .dark
#warning("Store theme in UserDefaults")
/// Toggles the theme.
static func toggleTheme() {
switch GEUserSettings.theme {
case .light: theme = .dark
case .dark: theme = .light
}
NotificationCenter.default.post(name: Notification.Name("UpdateThemeNotification"), object: nil)
}
}
GEView
GEView
是我自定义的 UIView
子类。这是替代而不是我对 UIView
的扩展。它现在看起来类似于:
/// UIView subclass to allow creating corners, shadows, and borders in storyboards.
@IBDesignable
final class GEView: UIView {
// MARK: - Initializers
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Triggers when the theme is changed
NotificationCenter.default.addObserver(self, selector: #selector(updateBackgroundColorNotification), name: Notification.Name("UpdateThemeNotification"), object: nil)
}
@objc
private func updateBackgroundColorNotification() {
updateBackgroundColor()
}
/* ... */
// MARK: - Background
@IBInspectable
var lightBackgroundColor: UIColor? {
didSet {
updateBackgroundColor()
}
}
@IBInspectable
var darkBackgroundColor: UIColor? {
didSet {
updateBackgroundColor()
}
}
/// Updates the background color depending on the theme.
private func updateBackgroundColor() {
switch GEUserSettings.theme {
case .light: backgroundColor = self.lightBackgroundColor
case .dark: backgroundColor = self.darkBackgroundColor
}
}
}
更新通过 motionBegan(_:with:)
override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
super.motionBegan(motion, with: event)
// Toggles the theme and update the views
GEUserSettings.toggleTheme()
drawerViewModel.updateBlurEffect(drawerView: drawerView)
}
然后删除并重新创建模糊,如下所示:
/// Creates the blur effect behind the collection view.
func updateBlurEffect(drawerView: GEView) {
if let blurView = drawerView.subviews[0] as? UIVisualEffectView {
blurView.removeFromSuperview()
}
let blurEffect: UIBlurEffect = {
switch GEUserSettings.theme {
case .light: return UIBlurEffect(style: .light)
case .dark: return UIBlurEffect(style: .dark)
}
}()
let blurView = UIVisualEffectView(effect: blurEffect)
drawerView.addSubview(blurView)
drawerView.sendSubviewToBack(blurView)
GEConstraints.fillView(with: blurView, for: drawerView)
}
这甚至不需要退出应用程序或重新加载视图控制器,它会立即发生!
额外(动画)
如果您愿意,还可以通过更改 updateBackgroundColor()
函数来设置颜色变化的动画:
/// Updates the background color depending on the theme.
private func updateBackgroundColor() {
UIView.animate(withDuration: 0.25) {
switch GEUserSettings.theme {
case .light: self.backgroundColor = self.lightBackgroundColor
case .dark: self.backgroundColor = self.darkBackgroundColor
}
}
}
您也可以为模糊设置动画:
/// Creates the blur effect behind the collection view.
func updateBlurEffect(drawerView: GEView) {
if let blurView = drawerView.subviews[0] as? UIVisualEffectView {
UIView.animate(withDuration: 0.25, animations: {
blurView.alpha = 0
}, completion: { _ in
blurView.removeFromSuperview()
})
}
let blurEffect: UIBlurEffect = {
switch GEUserSettings.theme {
case .light: return UIBlurEffect(style: .light)
case .dark: return UIBlurEffect(style: .dark)
}
}()
let blurView = UIVisualEffectView(effect: blurEffect)
blurView.alpha = 0
drawerView.addSubview(blurView)
drawerView.sendSubviewToBack(blurView)
GEConstraints.fillView(with: blurView, for: drawerView)
UIView.animate(withDuration: 0.25, animations: {
blurView.alpha = 1
})
}