Skip to content

Commit

Permalink
improve tab bar gradient and app theme update propagation
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-dydx committed Sep 23, 2024
1 parent 099de7a commit 31c0e5b
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 44 deletions.
71 changes: 42 additions & 29 deletions UIToolkits/UIToolkits/_View/GradientView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
}

29 changes: 18 additions & 11 deletions dydx/dydxViews/dydxViews/SwiftUIHosting/HostingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -36,12 +37,17 @@ public struct HostingViewControllerConfiguration {
}

open class HostingViewController<V: View, VM: PlatformViewModel>: TrackingViewController, UIViewControllerEmbeddingProtocol {

private var hostingController: UIHostingController<AnyView>?
private let presenterView = ObjectPresenterView()
private var configuration: HostingViewControllerConfiguration = .default

private let gradientView = UIImageView()
private var subscriptions = Set<AnyCancellable>()

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<VM>?

Expand Down Expand Up @@ -97,14 +103,16 @@ open class HostingViewController<V: View, VM: PlatformViewModel>: 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) {
Expand Down Expand Up @@ -143,7 +151,7 @@ open class HostingViewController<V: View, VM: PlatformViewModel>: TrackingViewCo
}

override public var preferredStatusBarStyle: UIStatusBarStyle {
switch currentThemeType {
switch dydxThemeSettings.shared.currentThemeType {
case .dark, .system, .classicDark:
return .lightContent
case .light:
Expand All @@ -155,9 +163,9 @@ open class HostingViewController<V: View, VM: PlatformViewModel>: 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()
Expand Down Expand Up @@ -205,8 +213,7 @@ open class HostingViewController<V: View, VM: PlatformViewModel>: 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
}
}

Expand Down
8 changes: 6 additions & 2 deletions dydx/dydxViews/dydxViews/Themes/dydxThemes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
Expand Down Expand Up @@ -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")
}
Expand Down
2 changes: 1 addition & 1 deletion dydx/dydxViews/dydxViews/_v4/Auth/dydxSecurityView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion dydx/dydxViews/dydxViews/_v4/Update/dydxUpdateView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 31c0e5b

Please sign in to comment.