我想重新加载在我的视图控制器各方面的意见,主题之间切换(类似于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
in代码的方法,因此它在中创建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)
或不算崩溃),或在使用应用程序时重新加载它。
我试图关闭然后重新加载视图控制器,如上面的代码所示。我要重装的一个显示在基本视图控制器的顶部。
当我使用情节提要板时,如何进行这项工作?
编辑-添加了我的亮/暗模式的图像,使我的问题更清晰:
我终于弄清楚了,使用NotificationCenter
!
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
是我的的自定义子类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
})
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句