subnav and tab bar color changes

This commit is contained in:
Scott Pfeil 2022-03-07 01:03:36 -05:00
parent da646a29a6
commit b4af1abe81
9 changed files with 255 additions and 62 deletions

View File

@ -272,6 +272,7 @@
AAE7270E24AC8B9300A3ED0E /* HeadersH2CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */; };
AAE96FA225341F6A0037A989 /* ListStoreLocatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE96FA125341F6A0037A989 /* ListStoreLocatorModel.swift */; };
AAE96FA525341F7D0037A989 /* ListStoreLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE96FA425341F7D0037A989 /* ListStoreLocator.swift */; };
AF97288627D2BF63009DC250 /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF97288527D2BF63009DC250 /* NavigationBar.swift */; };
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; };
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
@ -855,6 +856,7 @@
AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLink.swift; sourceTree = "<group>"; };
AAE96FA125341F6A0037A989 /* ListStoreLocatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStoreLocatorModel.swift; sourceTree = "<group>"; };
AAE96FA425341F7D0037A989 /* ListStoreLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStoreLocator.swift; sourceTree = "<group>"; };
AF97288527D2BF63009DC250 /* NavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBar.swift; sourceTree = "<group>"; };
BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = "<group>"; };
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
@ -1826,6 +1828,7 @@
children = (
D23EA7FC247EBB7500D60C34 /* Buttons */,
D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */,
AF97288527D2BF63009DC250 /* NavigationBar.swift */,
);
path = NavigationBar;
sourceTree = "<group>";
@ -2740,6 +2743,7 @@
D260106123D0C02A00764D80 /* StackItemModelProtocol.swift in Sources */,
0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */,
012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */,
AF97288627D2BF63009DC250 /* NavigationBar.swift in Sources */,
D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */,
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */,
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */,

View File

@ -10,10 +10,46 @@ import Foundation
public class TabBarModel: MoleculeModelProtocol {
public static var identifier: String = "tabBar"
public var backgroundColor: Color? = Color(uiColor: .white)
public var tabs: [TabBarItemModel]
public var selectedColor = Color(uiColor: .mvmBlack)
public var unSelectedColor = Color(uiColor: .mvmCoolGray6)
open var _backgroundColor: Color?
open var backgroundColor: Color? {
get {
if let backgroundColor = _backgroundColor { return backgroundColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmBlack) }
return Color(uiColor: .mvmWhite)
}
set {
_backgroundColor = newValue
}
}
open var _selectedColor: Color?
open var selectedColor: Color {
get {
if let selectedColor = _selectedColor { return selectedColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmWhite) }
return Color(uiColor: .mvmBlack)
}
set {
_selectedColor = newValue
}
}
open var _unSelectedColor: Color?
open var unSelectedColor: Color {
get {
if let unselectedColor = _unSelectedColor { return unselectedColor }
return Color(uiColor: .mvmCoolGray6)
}
set {
_unSelectedColor = newValue
}
}
public var style: NavigationItemStyle? = NavigationItemStyle.dark
// Must be capped to 0...(tabs.count - 1)
public var selectedTab: Int = 0
@ -25,6 +61,7 @@ public class TabBarModel: MoleculeModelProtocol {
case selectedColor
case unSelectedColor
case selectedTab
case style
}
public init(with tabs: [TabBarItemModel]) {
@ -46,16 +83,20 @@ public class TabBarModel: MoleculeModelProtocol {
if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedTab) {
selectedTab = index
}
if let style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) {
self.style = style
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(tabs, forKey: .tabs)
try container.encode(backgroundColor, forKey: .backgroundColor)
try container.encode(selectedColor, forKey: .selectedColor)
try container.encode(unSelectedColor, forKey: .unSelectedColor)
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(_selectedColor, forKey: .selectedColor)
try container.encodeIfPresent(_unSelectedColor, forKey: .unSelectedColor)
try container.encode(selectedTab, forKey: .selectedTab)
try container.encodeIfPresent(style, forKey: .style)
}
}

View File

@ -152,8 +152,7 @@ import UIKit
self.delegateObject = delegateObject
self.additionalData = additionalData
selectedIndex = tabsModel?.selectedIndex ?? 0
// TODO: Commented out until we have model support for bar color. Should also do unselected color.
//selectionLine.backgroundColor = tabsModel?.selectedColor.uiColor
selectionLine.backgroundColor = tabsModel?.selectedBarColor.uiColor
reloadData()
}
}
@ -333,7 +332,7 @@ extension Tabs {
if selected {
label.textColor = tabsModel?.selectedColor.uiColor ?? .black
} else {
label.textColor = .mvmCoolGray6
label.textColor = tabsModel?.unselectedColor.uiColor ?? .mvmCoolGray6
}
updateAccessibility(indexPath: indexPath, selected: selected, tabsModel: tabsModel)
}

View File

@ -10,19 +10,72 @@ import UIKit
public class TabsModel: MoleculeModelProtocol {
public static var identifier: String = "tabs"
public var backgroundColor: Color?
public var tabs: [TabItemModel]
public var selectedColor = Color(uiColor: .black)
open var style: NavigationItemStyle? = .dark
open var _backgroundColor: Color?
open var backgroundColor: Color? {
get {
if let backgroundColor = _backgroundColor { return backgroundColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmBlack) }
return Color(uiColor: .mvmWhite)
}
set {
_backgroundColor = newValue
}
}
open var _selectedColor: Color?
open var selectedColor: Color {
get {
if let selectedColor = _selectedColor { return selectedColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmWhite) }
return Color(uiColor: .mvmBlack)
}
set {
_selectedColor = newValue
}
}
open var _unselectedColor: Color?
open var unselectedColor: Color {
get {
if let unselectedColor = _unselectedColor { return unselectedColor }
return Color(uiColor: .mvmCoolGray6)
}
set {
_unselectedColor = newValue
}
}
open var _selectedBarColor: Color?
open var selectedBarColor: Color {
get {
if let selectedBarColor = _selectedBarColor { return selectedBarColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmWhite) }
return Color(uiColor: .mvmRed)
}
set {
_selectedBarColor = newValue
}
}
// Must be capped to 0...(tabs.count - 1)
public var selectedIndex: Int = 0
private enum CodingKeys: String, CodingKey {
case moleculeName
case tabs
case backgroundColor
case selectedColor
case unselectedColor
case selectedBarColor
case selectedIndex
case moleculeName
case style
}
public init(with tabs: [TabItemModel]) {
@ -33,8 +86,11 @@ public class TabsModel: MoleculeModelProtocol {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
tabs = try typeContainer.decode([TabItemModel].self, forKey: .tabs)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) {
selectedColor = color
_selectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor)
_unselectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unselectedColor)
_selectedBarColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedBarColor)
if let style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) {
self.style = style
}
if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) {
selectedIndex = index
@ -45,9 +101,12 @@ public class TabsModel: MoleculeModelProtocol {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(tabs, forKey: .tabs)
try container.encode(backgroundColor, forKey: .backgroundColor)
try container.encode(selectedColor, forKey: .selectedColor)
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(_selectedColor, forKey: .selectedColor)
try container.encodeIfPresent(_unselectedColor, forKey: .unselectedColor)
try container.encodeIfPresent(_selectedBarColor, forKey: .selectedBarColor)
try container.encode(selectedIndex, forKey: .selectedIndex)
try container.encodeIfPresent(style, forKey: .style)
}
}

View File

@ -0,0 +1,39 @@
//
// NavigationBar.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 3/4/22.
// Copyright © 2022 Verizon Wireless. All rights reserved.
//
import UIKit
open class NavigationBar: UINavigationBar, MoleculeViewProtocol {
public var line: Line = Line(model: LineModel(type: .standard), nil, nil)
public required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
public override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
open func setupView() {
line.addLine(to: self, edge: .bottom, useMargin: false)
reset()
}
public func reset() {
set(with: NavigationItemModel(), nil, nil)
}
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? NavigationItemModel else { return }
NavigationController.setNavigation(bar: self, model: model)
line.setOptional(with: model.line, delegateObject, additionalData)
}
}

View File

@ -6,6 +6,10 @@
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
public enum NavigationItemStyle: String, Codable {
case light
case dark
}
open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
//--------------------------------------------------
@ -14,12 +18,39 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
open class var identifier: String { "navigationBar" }
private let defaultHidesSystemBackButton = true
open var title: String?
open var hidden: Bool
open var backgroundColor: Color?
open var tintColor: Color
open var line: LineModel?
open var hidden = false
open var line = LineModel(type: .standard)
open var hidesSystemBackButton = true
open var style: NavigationItemStyle? = .dark
open var _backgroundColor: Color?
open var backgroundColor: Color? {
get {
if let backgroundColor = _backgroundColor { return backgroundColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmBlack) }
return Color(uiColor: .mvmWhite)
}
set {
_backgroundColor = newValue
}
}
open var _tintColor: Color?
open var tintColor: Color {
get {
if let tintColor = _tintColor { return tintColor }
if let style = style,
style == .dark { return Color(uiColor: .mvmWhite) }
return Color(uiColor: .mvmBlack)
}
set {
_tintColor = newValue
}
}
/// If true, we add the button in the backButton property. If false we do not add the button. If nil, we add the button if the controller is not the bottom of the stack
open var alwaysShowBackButton: Bool?
@ -33,12 +64,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
// MARK: - Initializer
//--------------------------------------------------
public init() {
hidden = false
backgroundColor = Color(uiColor: .mvmWhite)
tintColor = Color(uiColor: .mvmBlack)
line = LineModel(type: .standard)
}
public init() {}
//--------------------------------------------------
// MARK: - Keys
@ -57,6 +83,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
case additionalLeftButtons
case additionalRightButtons
case titleView
case style
}
//--------------------------------------------------
@ -66,16 +93,25 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .mvmWhite)
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .mvmBlack)
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .standard)
hidesSystemBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidesSystemBackButton) ?? true
if let hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) {
self.hidden = hidden
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
_tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor)
if let line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) {
self.line = line
}
if let hidesSystemBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidesSystemBackButton) {
self.hidesSystemBackButton = hidesSystemBackButton
}
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton)
backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton)
additionalLeftButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalLeftButtons)
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
if let style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) {
self.style = style
}
}
open func encode(to encoder: Encoder) throws {
@ -83,8 +119,8 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(title, forKey: .title)
try container.encode(hidden, forKey: .hidden)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(tintColor, forKey: .tintColor)
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(_tintColor, forKey: .tintColor)
try container.encodeIfPresent(line, forKey: .line)
try container.encode(hidesSystemBackButton, forKey: .hidesSystemBackButton)
try container.encodeIfPresent(alwaysShowBackButton, forKey: .alwaysShowBackButton)
@ -92,6 +128,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons)
try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons)
try container.encodeModelIfPresent(titleView, forKey: .titleView)
try container.encodeIfPresent(style, forKey: .style)
}
}

View File

@ -13,7 +13,6 @@ public protocol NavigationItemModelProtocol {
var hidden: Bool { get set }
var backgroundColor: Color? { get set }
var tintColor: Color { get set }
var line: LineModel? { get set }
var hidesSystemBackButton: Bool { get set }
var alwaysShowBackButton: Bool? { get set }
var backButton: (NavigationButtonModelProtocol & MoleculeModelProtocol)? { get set }

View File

@ -9,28 +9,22 @@
import UIKit
@objcMembers open class NavigationController: UINavigationController, MVMCoreViewManagerViewControllerProtocol {
public var separatorView: Line?
public weak var manager: (UIViewController & MVMCoreViewManagerProtocol)?
/// TODO: Remove after removing legacy connections.
public var separatorView: Line? {
get {
return (navigationBar as? NavigationBar)?.line
}
}
/// Getter for the main navigation controller
public static func navigationController() -> Self? {
return MVMCoreActionUtility.initializerClassCheck(MVMCoreUISession.sharedGlobal()?.navigationController, classToVerify: self) as? Self
}
/// Provides MVM styling to the navigation bar. Returns a reference to the line.
public static func style(_ navigationBar: UINavigationBar) -> Line {
navigationBar.backgroundColor = .white
navigationBar.shadowImage = UIImage()
navigationBar.isOpaque = true
navigationBar.tintColor = .black
navigationBar.titleTextAttributes = [NSAttributedString.Key.font: MFStyler.fontBoldBodySmall(false)];
return Line(pinTo: navigationBar, edge: .bottom, useMargin: false)
}
/// Sets up the application with a navigation controller
public static func setupNavigationController() -> Self? {
let navigationController = self.init()
navigationController.separatorView = style(navigationController.navigationBar)
public static func setupNavigationController() -> NavigationController {
let navigationController = NavigationController(navigationBarClass: NavigationBar.self, toolbarClass: nil)
MVMCoreUISession.sharedGlobal()?.navigationController = navigationController
MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController
MVMCoreNavigationHandler.shared()?.navigationController = navigationController
@ -39,8 +33,8 @@ import UIKit
}
/// Sets up the application with a navigation controller as the main container.
public static func setupNavigationControllerAsMainController() -> Self? {
guard let navigationController = setupNavigationController() else { return nil }
public static func setupNavigationControllerAsMainController() -> NavigationController {
let navigationController = setupNavigationController()
MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController)
return navigationController
}
@ -84,18 +78,38 @@ import UIKit
/// Convenience function for setting the navigation bar ui, except for the buttons.
public static func setNavigationBarUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) {
let navigationBar = navigationController.navigationBar
if let model = navigationItemModel as? NavigationItemModelProtocol & MoleculeModelProtocol,
let navigationBar = navigationBar as? MoleculeViewProtocol {
navigationBar.set(with: model, nil, nil)
} else {
setNavigation(bar: navigationController.navigationBar, model: navigationItemModel)
}
navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true)
navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white
let tint = navigationItemModel.tintColor.uiColor
navigationController.navigationBar.tintColor = tint
// Have the navigation title match the tint color
navigationController.navigationBar.titleTextAttributes?.updateValue(tint, forKey: .foregroundColor)
// Update line.
if let navigationController = navigationController as? NavigationController {
navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none
}
/// Convenience function for settin the navigation bar by the model
public static func setNavigation(bar: UINavigationBar, model: NavigationItemModelProtocol) {
let font = MFStyler.fontBoldBodySmall(false)
let backgroundColor = model.backgroundColor?.uiColor
let tint = model.tintColor.uiColor
bar.tintColor = tint
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
appearance.titleTextAttributes = [NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: tint];
appearance.backgroundColor = backgroundColor
appearance.titleTextAttributes.updateValue(tint, forKey: .foregroundColor)
bar.standardAppearance = appearance
bar.scrollEdgeAppearance = appearance
} else {
// Fallback on earlier versions
bar.shadowImage = UIImage()
bar.isOpaque = true
bar.titleTextAttributes = [NSAttributedString.Key.font: font,
NSAttributedString.Key.foregroundColor: tint];
bar.barTintColor = backgroundColor
}
}

View File

@ -119,7 +119,8 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
/// Hides the navigation bar for the page.
open func hideNavigationBarLine(for viewController: UIViewController) {
(viewController as? PageProtocol)?.pageModel?.navigationBar?.line?.type = .none
guard let navigationBar = navigationController?.navigationBar as? NavigationBar else { return }
navigationBar.isHidden = true
}
open override func updateViews() {