From ddc1e435aad95f473ec78ba15e3bc93b287e1ee2 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 23 Sep 2024 13:28:18 -0400 Subject: [PATCH] improve tab bar gradient and app theme update propagation --- .../UIToolkits/_View/GradientView.swift | 71 +++++++++++-------- .../HostingViewController.swift | 29 +++++--- .../dydxViews/Themes/dydxThemes.swift | 8 ++- .../dydxViews/_v4/Auth/dydxSecurityView.swift | 2 +- .../dydxViews/_v4/Update/dydxUpdateView.swift | 2 +- 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/UIToolkits/UIToolkits/_View/GradientView.swift b/UIToolkits/UIToolkits/_View/GradientView.swift index 09e86548a..12a8170aa 100644 --- a/UIToolkits/UIToolkits/_View/GradientView.swift +++ b/UIToolkits/UIToolkits/_View/GradientView.swift @@ -2,45 +2,58 @@ // GradientView.swift // UIToolkits // -// Created by Qiang Huang on 9/6/21. -// Copyright © 2021 dYdX. All rights reserved. +// Created by Mike Maguire on 9/20/24. +// Copyright © 2024 dYdX. All rights reserved. // import UIKit -@objc public class GradientView: UIView { - override open class var layerClass: AnyClass { - return CAGradientLayer.classForCoder() +public class GradientView: UIView { + + // Configurable properties + public var gradientColors: [UIColor] { + didSet { + gradientLayer.colors = gradientColors.map { $0.cgColor } + } } - @IBInspectable var startColor: UIColor? - @IBInspectable var endColor: UIColor? - - private var gradientLayer: CAGradientLayer? { - return layer as? CAGradientLayer + private let startPoint: CGPoint + private let endPoint: CGPoint + private let gradientLayer = CAGradientLayer() + + // Initializers + public init(gradientColors: [UIColor], + startPoint: CGPoint = CGPoint(x: 0.5, y: 0), + endPoint: CGPoint = CGPoint(x: 0.5, y: 1)) { + self.gradientColors = gradientColors + self.startPoint = startPoint + self.endPoint = endPoint + super.init(frame: .zero) + setupGradientLayer() } - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } - - public override func awakeFromNib() { - super.awakeFromNib() - gradientLayer?.startPoint = CGPoint(x: 0.0, y: 0.5) - gradientLayer?.endPoint = CGPoint(x: 1.0, y: 0.5) - setupLayer() + + // Setup gradient layer + private func setupGradientLayer() { + gradientLayer.colors = gradientColors.map { $0.cgColor } + gradientLayer.startPoint = startPoint + gradientLayer.endPoint = endPoint + layer.insertSublayer(gradientLayer, at: 0) } - - public func set(startColor: UIColor?, endColor: UIColor?) { - self.startColor = startColor - self.endColor = endColor - setupLayer() + + // Adjust gradient layer's frame when the view's bounds change + public override func layoutSubviews() { + super.layoutSubviews() + gradientLayer.frame = bounds } - private func setupLayer() { - if let startColor = startColor, let endColor = endColor { - gradientLayer?.colors = [startColor.cgColor, endColor.cgColor] - } else { - gradientLayer?.colors = nil + public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) { + setupGradientLayer() } } } + diff --git a/dydx/dydxViews/dydxViews/SwiftUIHosting/HostingViewController.swift b/dydx/dydxViews/dydxViews/SwiftUIHosting/HostingViewController.swift index 4361bf71a..3a724cc61 100644 --- a/dydx/dydxViews/dydxViews/SwiftUIHosting/HostingViewController.swift +++ b/dydx/dydxViews/dydxViews/SwiftUIHosting/HostingViewController.swift @@ -16,6 +16,7 @@ import UIToolkits import PlatformRouting import FloatingPanel import Utilities +import Combine public struct HostingViewControllerConfiguration { public init(ignoreSafeArea: Bool = true, fixedHeight: CGFloat? = nil, gradientTabbar: Bool = false, disableNavigationController: Bool = false) { @@ -36,12 +37,17 @@ public struct HostingViewControllerConfiguration { } open class HostingViewController: TrackingViewController, UIViewControllerEmbeddingProtocol { - + private var hostingController: UIHostingController? private let presenterView = ObjectPresenterView() private var configuration: HostingViewControllerConfiguration = .default - - private let gradientView = UIImageView() + private var subscriptions = Set() + + static private var gradientColors: [UIColor] { [ThemeColor.SemanticColor.layer2.uiColor.withAlphaComponent(0.01), + ThemeColor.SemanticColor.layer2.uiColor.withAlphaComponent(0.90)] } + private let gradientView = GradientView(gradientColors: HostingViewController.gradientColors, + startPoint: CGPoint(x: 0.5, y: 0), + endPoint: CGPoint(x: 0.5, y: 0.25)) public private(set) var presenter: HostedViewPresenter? @@ -97,14 +103,16 @@ open class HostingViewController: TrackingViewCo tabBarController?.tabBar.shadowImage = UIImage() tabBarController?.tabBar.backgroundImage = UIImage() - gradientView.backgroundColor = .clear - gradientView.contentMode = .scaleToFill view.addSubview(gradientView) gradientView.snp.updateConstraints { make in make.leading.trailing.bottom.equalToSuperview() - make.height.equalTo(83) + make.height.equalTo(96) } } + + dydxThemeSettings.shared.$currentThemeType.sink { [weak self] _ in + self?.updateTabItemGradient() + }.store(in: &subscriptions) } open override func viewWillAppear(_ animated: Bool) { @@ -143,7 +151,7 @@ open class HostingViewController: TrackingViewCo } override public var preferredStatusBarStyle: UIStatusBarStyle { - switch currentThemeType { + switch dydxThemeSettings.shared.currentThemeType { case .dark, .system, .classicDark: return .lightContent case .light: @@ -155,9 +163,9 @@ open class HostingViewController: TrackingViewCo super.traitCollectionDidChange(previousTraitCollection) if ThemeSettings.respondsToSystemTheme { - if UITraitCollection.current.userInterfaceStyle == .dark, currentThemeType != .dark { + if UITraitCollection.current.userInterfaceStyle == .dark, dydxThemeSettings.shared.currentThemeType != .dark { ThemeSettings.applyDarkTheme() - } else if UITraitCollection.current.userInterfaceStyle == .light, currentThemeType != .light { + } else if UITraitCollection.current.userInterfaceStyle == .light, dydxThemeSettings.shared.currentThemeType != .light { ThemeSettings.applyLightTheme() } updateTabItemGradient() @@ -205,8 +213,7 @@ open class HostingViewController: TrackingViewCo } private func updateTabItemGradient() { - let gradientImage = UIImage.named("gradient_tabbar", bundles: Bundle.particles) - gradientView.image = gradientImage?.withTintColor(ThemeColor.SemanticColor.layer2.uiColor) + gradientView.gradientColors = HostingViewController.gradientColors } } diff --git a/dydx/dydxViews/dydxViews/Themes/dydxThemes.swift b/dydx/dydxViews/dydxViews/Themes/dydxThemes.swift index 25f7e842d..3a6135a37 100644 --- a/dydx/dydxViews/dydxViews/Themes/dydxThemes.swift +++ b/dydx/dydxViews/dydxViews/Themes/dydxThemes.swift @@ -13,6 +13,11 @@ import UIKit import SwiftUI import Utilities +class dydxThemeSettings { + static let shared = dydxThemeSettings() + @Published fileprivate(set) var currentThemeType: dydxThemeType = .dark +} + public enum dydxThemeType: String { case dark case classicDark = "classic_dark" @@ -34,7 +39,6 @@ public enum dydxThemeType: String { } } -public var currentThemeType = dydxThemeType.dark private var loadFontOnce: Void = { let fonts = Bundle(for: dydxViewBundleClass.self).urls(forResourcesWithExtension: "otf", subdirectory: nil) @@ -86,7 +90,7 @@ public extension ThemeSettings { case .classicDark, .dark, .light: if let config = theme.config { shared.themeConfig = config - currentThemeType = theme + dydxThemeSettings.shared.currentThemeType = theme } else { assertionFailure("\(theme.configFileName ?? "theme config file") not found") } diff --git a/dydx/dydxViews/dydxViews/_v4/Auth/dydxSecurityView.swift b/dydx/dydxViews/dydxViews/_v4/Auth/dydxSecurityView.swift index 238a65e16..69d1567a7 100644 --- a/dydx/dydxViews/dydxViews/_v4/Auth/dydxSecurityView.swift +++ b/dydx/dydxViews/dydxViews/_v4/Auth/dydxSecurityView.swift @@ -71,7 +71,7 @@ public class dydxSecurityViewModel: PlatformViewModel { private func logoImage(parentStyle: ThemeStyle, styleKey: String?) -> PlatformView { let imageName: String - if currentThemeType == .light { + if dydxThemeSettings.shared.currentThemeType == .light { imageName = "brand_light" } else { imageName = "brand_dark" diff --git a/dydx/dydxViews/dydxViews/_v4/Update/dydxUpdateView.swift b/dydx/dydxViews/dydxViews/_v4/Update/dydxUpdateView.swift index 8bc83e071..42cad1e21 100644 --- a/dydx/dydxViews/dydxViews/_v4/Update/dydxUpdateView.swift +++ b/dydx/dydxViews/dydxViews/_v4/Update/dydxUpdateView.swift @@ -85,7 +85,7 @@ public class dydxUpdateViewModel: PlatformViewModel { private func logoImage(parentStyle: ThemeStyle, styleKey: String?) -> PlatformView { let imageName: String - if currentThemeType == .light { + if dydxThemeSettings.shared.currentThemeType == .light { imageName = "brand_light" } else { imageName = "brand_dark"