diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8d19a539..56e3492c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -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 */; }; + AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.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 */; }; @@ -857,6 +858,7 @@ AAE7270D24AC8B9300A3ED0E /* HeadersH2CaretLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH2CaretLink.swift; sourceTree = ""; }; AAE96FA125341F6A0037A989 /* ListStoreLocatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStoreLocatorModel.swift; sourceTree = ""; }; AAE96FA425341F7D0037A989 /* ListStoreLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListStoreLocator.swift; sourceTree = ""; }; + AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = ""; }; BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = ""; }; BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = ""; }; BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = ""; }; @@ -1535,6 +1537,15 @@ path = Miscellaneous; sourceTree = ""; }; + AFE4A1D427DFBB2700C458D0 /* NavigationController */ = { + isa = PBXGroup; + children = ( + D2B18B93236214AD00A9AEDC /* NavigationController.swift */, + AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */, + ); + path = NavigationController; + sourceTree = ""; + }; D202AFE2242A5F1400E5BEDF /* Extensions */ = { isa = PBXGroup; children = ( @@ -2072,9 +2083,9 @@ D29DF11921E68467003B2FB9 /* Containers */ = { isa = PBXGroup; children = ( + AFE4A1D427DFBB2700C458D0 /* NavigationController */, 0ABD1369237B18EE0081388D /* Views */, D29DF2B621E7BE66003B2FB9 /* SplitViewController */, - D2B18B93236214AD00A9AEDC /* NavigationController.swift */, ); path = Containers; sourceTree = ""; @@ -2637,6 +2648,7 @@ DBC4391922442197001AB423 /* DashLine.swift in Sources */, D2ED27FC254B0E0300A1C293 /* MVMCoreAlertObject+Swift.swift in Sources */, D264FAAA2440F97600D98315 /* CollectionView.swift in Sources */, + AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */, AAC23FAD24D92A0D009208DF /* ListThreeColumnSpeedTestModel.swift in Sources */, BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */, 01F2C20527C81F9700DC3D36 /* SubNavSwipeAnimator.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 22d33b1f..76016292 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -18,10 +18,6 @@ import UIKit get { return model as? LineModel } } - var lineBackgroundColor: Color? { - return (lineModel?.inverted ?? false) ? lineModel?.backgroundColor_inverted : lineModel?.backgroundColor - } - //-------------------------------------------------- // MARK: - Constraints //-------------------------------------------------- @@ -50,28 +46,33 @@ import UIKit addLine(to: view, edge: edge, useMargin: useMargin) } + public init() { + super.init(frame: .zero) + model = LineModel(type: .standard) + } + + public override init(frame: CGRect) { + super.init(frame: frame) + model = LineModel(type: .standard) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + model = LineModel(type: .standard) + } + + public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + super.init(model: model, delegateObject, additionalData) + } + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- open func setStyle(_ style: LineModel.Style) { - - switch style { - case .standard: - updateLineConstraints(constant: 1) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmCoolGray3 - case .thin: - updateLineConstraints(constant: 1) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack - case .medium: - updateLineConstraints(constant: 2) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack - case .heavy: - updateLineConstraints(constant: 4) - backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack - case .none: - updateLineConstraints(constant: 0) - } + lineModel?.type = style + backgroundColor = lineModel?.backgroundColor?.uiColor + updateLineConstraints(constant: lineModel?.thickness ?? 1) } open func shouldBeVisible() -> Bool { @@ -90,12 +91,10 @@ import UIKit open override func setupView() { super.setupView() - heightConstraint = heightAnchor.constraint(equalToConstant: 1) heightConstraint?.isActive = true widthConstraint = widthAnchor.constraint(equalToConstant: 1) widthConstraint?.isActive = false - setStyle(.standard) } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { @@ -111,19 +110,7 @@ import UIKit } public override static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - - guard let type = (model as? LineModel)?.type else { return 1 } - - switch type { - case .none: - return 0 - case .medium: - return 2 - case .heavy: - return 4 - default: - return 1 - } + return (model as? LineModel)?.thickness ?? 1 } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 0f67b3f0..a3073f52 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -54,7 +54,39 @@ import UIKit //TODO: use color insted of backgroundColor. Needs server changes // public var color: Color? - public var backgroundColor: Color? + private var _backgroundColor: Color? + public var backgroundColor: Color? { + get { + if inverted { return backgroundColor_inverted } + if let backgroundColor = _backgroundColor { return backgroundColor } + if type == .standard { return Color(uiColor: .mvmCoolGray3) } + return Color(uiColor: .mvmBlack) + } + set { + _backgroundColor = newValue + } + } + + private var _thickness: CGFloat? + public var thickness: CGFloat { + get { + if let thickness = _thickness { return thickness } + switch type { + case .heavy: + return 4 + case .medium: + return 2 + case .none: + return 0 + default: + return 1 + } + } + set { + _thickness = newValue + } + } + public var backgroundColor_inverted: Color = Color(uiColor: .mvmWhite) public var inverted: Bool = false @@ -90,6 +122,7 @@ import UIKit case frequency case inverted case useVerticalLine + case thickness } //-------------------------------------------------- @@ -117,6 +150,7 @@ import UIKit backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine) + _thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) } public func encode(to encoder: Encoder) throws { @@ -125,8 +159,9 @@ import UIKit try container.encode(type, forKey: .type) try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(backgroundColor_inverted, forKey: .backgroundColor_inverted) try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine) + try container.encodeIfPresent(_thickness, forKey: .thickness) } } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index fc3e9449..2a55b31e 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -8,15 +8,51 @@ import Foundation -public class TabBarModel: MoleculeModelProtocol { +open 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 tabs: [TabBarItemModel] + + private 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 + } + } + + private 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 + } + } + + private var _unSelectedColor: Color? + open var unSelectedColor: Color { + get { + if let unselectedColor = _unSelectedColor { return unselectedColor } + return Color(uiColor: .mvmCoolGray6) + } + set { + _unSelectedColor = newValue + } + } + + open var style: NavigationItemStyle? // Must be capped to 0...(tabs.count - 1) - public var selectedTab: Int = 0 + open var selectedTab: Int = 0 private enum CodingKeys: String, CodingKey { case moleculeName @@ -25,6 +61,7 @@ public class TabBarModel: MoleculeModelProtocol { case selectedColor case unSelectedColor case selectedTab + case style } public init(with tabs: [TabBarItemModel]) { @@ -46,24 +83,26 @@ public class TabBarModel: MoleculeModelProtocol { if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedTab) { selectedTab = index } + style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) } - public func encode(to encoder: Encoder) throws { + open 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) } } -public class TabBarItemModel: Codable { - var title: String? - var image: String - var action: ActionModelProtocol - var accessibilityText: String? +open class TabBarItemModel: Codable { + open var title: String? + open var image: String + open var action: ActionModelProtocol + open var accessibilityText: String? private enum CodingKeys: String, CodingKey { case title @@ -86,7 +125,7 @@ public class TabBarItemModel: Codable { accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) } - public func encode(to encoder: Encoder) throws { + open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(title, forKey: .title) try container.encode(image, forKey: .image) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 290ced62..7fdbc9b1 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -153,8 +153,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() } } @@ -338,7 +337,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) } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift index 64f8df4d..16897c67 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift @@ -8,21 +8,74 @@ import UIKit -public class TabsModel: MoleculeModelProtocol { +open 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 tabs: [TabItemModel] + + open var style: NavigationItemStyle? + + private 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 + } + } + + private 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 + } + } + + private var _unselectedColor: Color? + open var unselectedColor: Color { + get { + if let unselectedColor = _unselectedColor { return unselectedColor } + return Color(uiColor: .mvmCoolGray6) + } + set { + _unselectedColor = newValue + } + } + + private 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 + open 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,31 +86,35 @@ 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) + style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) if let index = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) { selectedIndex = index } } - public func encode(to encoder: Encoder) throws { + open 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.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) } } -public class TabItemModel: Codable { - public var label: LabelModel - public var action: ActionModelProtocol? +open class TabItemModel: Codable { + open var label: LabelModel + open var action: ActionModelProtocol? - init(label: LabelModel) { + public init(label: LabelModel) { self.label = label } @@ -66,7 +123,7 @@ public class TabItemModel: Codable { case action } - func setDefaults() { + open func setDefaults() { if label.textAlignment == nil { label.textAlignment = .center } @@ -85,7 +142,7 @@ public class TabItemModel: Codable { setDefaults() } - public func encode(to encoder: Encoder) throws { + open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeModel(label, forKey: .label) try container.encodeModelIfPresent(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index d8126508..b7eaf2d8 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -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? = LineModel(type: .standard) open var hidesSystemBackButton = true + open var style: NavigationItemStyle? + + private 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 + } + } + + private 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,23 @@ 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) + style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style) } open func encode(to encoder: Encoder) throws { @@ -83,8 +117,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 +126,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) } } diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift deleted file mode 100644 index c2b63a6e..00000000 --- a/MVMCoreUI/Containers/NavigationController.swift +++ /dev/null @@ -1,201 +0,0 @@ -// -// NavigationController.swift -// MVMCoreUI -// -// Created by Scott Pfeil on 10/24/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import UIKit - -@objcMembers open class NavigationController: UINavigationController, MVMCoreViewManagerViewControllerProtocol { - public var separatorView: Line? - public weak var manager: (UIViewController & MVMCoreViewManagerProtocol)? - - /// 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) - MVMCoreUISession.sharedGlobal()?.navigationController = navigationController - MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController - MVMCoreNavigationHandler.shared()?.navigationController = navigationController - MVMCoreNavigationHandler.shared()?.addDelegate(navigationController) - return navigationController - } - - /// Sets up the application with a navigation controller as the main container. - public static func setupNavigationControllerAsMainController() -> Self? { - guard let navigationController = setupNavigationController() else { return nil } - MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController) - return navigationController - } - - /// Convenience function for setting the navigation item. - public static func setNavigationItem(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { - viewController.navigationItem.title = navigationItemModel.title - viewController.navigationItem.accessibilityLabel = navigationItemModel.title - viewController.navigationItem.hidesBackButton = navigationItemModel.hidesSystemBackButton - viewController.navigationItem.leftItemsSupplementBackButton = !navigationItemModel.hidesSystemBackButton - setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - setNavigationTitleView(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - } - - /// Convenience function for setting the navigation buttons. - public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { - let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject - var leftItems: [UIBarButtonItem] = [] - if navigationItemModel.hidesSystemBackButton, - navigationItemModel.alwaysShowBackButton != false { - if let backButtonModel = navigationItemModel.backButton, - MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController)?.count ?? 0 > 1 || navigationItemModel.alwaysShowBackButton ?? false { - leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) - } - if let leftItemModels = navigationItemModel.additionalLeftButtons { - for item in leftItemModels { - leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) - } - } - } - viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil - - var rightItems: [UIBarButtonItem] = [] - if let rightItemModels = navigationItemModel.additionalRightButtons { - for item in rightItemModels { - rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) - } - } - viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil - } - - /// Convenience function for setting the navigation bar ui, except for the buttons. - public static func setNavigationBarUI(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { - 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 setting the navigation titleView. - public static func setNavigationTitleView(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol?, viewController: UIViewController) { - let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject - if let titleViewModel = navigationItemModel?.titleView, let molecule = ModelRegistry.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { - viewController.navigationItem.titleView = molecule - } - } - - /// Convenience function to return the navigation model of the lowest controller traversing managers if applicable. - public func getNavigationModel(from viewController: UIViewController) -> NavigationItemModelProtocol? { - return (viewController as? PageProtocol)?.pageModel?.navigationBar - } - - /// Verifies the controller is the currently displayed controller. - public func isDisplayed(viewController: UIViewController) -> Bool { - guard let topViewController = topViewController, - viewController == MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { - return false - } - return true - } -} - -extension NavigationController: MVMCoreViewManagerProtocol { - public func getCurrentViewController() -> UIViewController? { - guard let topViewController = topViewController else { return nil } - return MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) - } - - public func containsPage(withPageType pageType: String?) -> Bool { - for controller in viewControllers { - if let manager = controller as? MVMCoreViewManagerProtocol, - manager.containsPage(withPageType: pageType) { - return true - } else if let controller = controller as? MVMCoreViewControllerProtocol, - controller.pageType == pageType { - return true - } - } - return false - } - - public func newDataReceived(in viewController: UIViewController) { - - if isDisplayed(viewController: viewController), - let topViewController = topViewController, - let model = getNavigationModel(from: viewController) { - Self.setNavigationItem(navigationController: self, navigationItemModel: model, viewController: topViewController) - Self.setNavigationBarUI(navigationController: self, navigationItemModel: model, viewController: topViewController) - } - manager?.newDataReceived?(in: viewController) - } - - public func willDisplay(_ viewController: UIViewController) { - if let topViewController = topViewController, - let model = getNavigationModel(from: viewController) { - Self.setNavigationItem(navigationController: self, navigationItemModel: model, viewController: topViewController) - } - manager?.willDisplay?(viewController) - } - - public func displayedViewController(_ viewController: UIViewController) { - if isDisplayed(viewController: viewController), - let topViewController = topViewController, - let model = getNavigationModel(from: viewController) { - Self.setNavigationBarUI(navigationController: self, navigationItemModel: model, viewController: topViewController) - } - manager?.displayedViewController?(viewController) - } -} - -extension NavigationController: MVMCorePresentationDelegateProtocol { - public func navigationController(_ navigationController: UINavigationController, prepareDisplayFor viewController: UIViewController) { - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController), - let model = getNavigationModel(from: newViewController) else { return } - Self.setNavigationItem(navigationController: self, navigationItemModel: model, viewController: viewController) - } - - public func navigationController(_ navigationController: UINavigationController, willDisplay viewController: UIViewController) { - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) - } - manager?.willDisplay?(newViewController) - } - - public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { - guard self == navigationController, - let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } - if let model = getNavigationModel(from: newViewController) { - Self.setNavigationBarUI(navigationController: self, navigationItemModel: model, viewController: viewController) - } - manager?.displayedViewController?(newViewController) - if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { - controller.viewControllerReady?(inManager: self) - } - } -} diff --git a/MVMCoreUI/Containers/NavigationController/NavigationController.swift b/MVMCoreUI/Containers/NavigationController/NavigationController.swift new file mode 100644 index 00000000..03c10595 --- /dev/null +++ b/MVMCoreUI/Containers/NavigationController/NavigationController.swift @@ -0,0 +1,136 @@ +// +// NavigationController.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 10/24/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class NavigationController: UINavigationController, MVMCoreViewManagerViewControllerProtocol { + public weak var manager: (UIViewController & MVMCoreViewManagerProtocol)? + + /// Getter for the main navigation controller + public static func navigationController() -> Self? { + return MVMCoreActionUtility.initializerClassCheck(MVMCoreUISession.sharedGlobal()?.navigationController, classToVerify: self) as? Self + } + + /// Sets up the application with a navigation controller + public static func setupNavigationController() -> Self? { + let navigationController = self.init() + MVMCoreUISession.sharedGlobal()?.navigationController = navigationController + MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController + MVMCoreNavigationHandler.shared()?.navigationController = navigationController + MVMCoreNavigationHandler.shared()?.addDelegate(navigationController) + navigationController.setNavigationBarUI(with: NavigationItemModel()) + return navigationController + } + + /// Sets up the application with a navigation controller as the main container. + public static func setupNavigationControllerAsMainController() -> Self? { + guard let navigationController = setupNavigationController() else { return nil } + MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController) + return navigationController + } + + /// Convenience function to return the navigation model of the lowest controller traversing managers if applicable. + public func getNavigationModel(from viewController: UIViewController) -> NavigationItemModelProtocol? { + return (viewController as? PageProtocol)?.pageModel?.navigationBar + } + + /// Verifies the controller is the currently displayed controller. + public func isDisplayed(viewController: UIViewController) -> Bool { + guard let topViewController = topViewController, + viewController == MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) else { + return false + } + return true + } +} + +extension NavigationController: MVMCoreViewManagerProtocol { + public func getCurrentViewController() -> UIViewController? { + guard let topViewController = topViewController else { return nil } + return MVMCoreUIUtility.getViewControllerTraversingManagers(topViewController) + } + + public func containsPage(withPageType pageType: String?) -> Bool { + for controller in viewControllers { + if let manager = controller as? MVMCoreViewManagerProtocol, + manager.containsPage(withPageType: pageType) { + return true + } else if let controller = controller as? MVMCoreViewControllerProtocol, + controller.pageType == pageType { + return true + } + } + return false + } + + public func newDataReceived(in viewController: UIViewController) { + + if isDisplayed(viewController: viewController), + let topViewController = topViewController, + let model = getNavigationModel(from: viewController) { + setNavigationItem(with: model, for: topViewController) + setNavigationBarUI(with: model) + } + manager?.newDataReceived?(in: viewController) + } + + public func willDisplay(_ viewController: UIViewController) { + if let topViewController = topViewController, + let model = getNavigationModel(from: viewController) { + setNavigationItem(with: model, for: topViewController) + } + manager?.willDisplay?(viewController) + } + + public func displayedViewController(_ viewController: UIViewController) { + if isDisplayed(viewController: viewController), + let model = getNavigationModel(from: viewController) { + setNavigationBarUI(with: model) + } + manager?.displayedViewController?(viewController) + } +} + +extension NavigationController: MVMCorePresentationDelegateProtocol { + public func navigationController(_ navigationController: UINavigationController, prepareDisplayFor viewController: UIViewController) { + guard self == navigationController, + let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController), + let model = getNavigationModel(from: newViewController) else { return } + setNavigationItem(with: model, for: viewController) + } + + public func navigationController(_ navigationController: UINavigationController, willDisplay viewController: UIViewController) { + guard self == navigationController, + let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) + } + manager?.willDisplay?(newViewController) + } + + public func navigationController(_ navigationController: UINavigationController, displayedViewController viewController: UIViewController) { + guard self == navigationController, + let newViewController = MVMCoreUIUtility.getViewControllerTraversingManagers(viewController) else { return } + if let model = getNavigationModel(from: newViewController) { + setNavigationBarUI(with: model) + } + manager?.displayedViewController?(newViewController) + if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { + controller.viewControllerReady?(inManager: self) + } + } +} + +extension UIColor { + func image(_ size: CGSize = CGSize(width: 1, height: 1)) -> UIImage { + return UIGraphicsImageRenderer(size: size).image { rendererContext in + self.setFill() + rendererContext.fill(CGRect(origin: .zero, size: size)) + } + } +} diff --git a/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift new file mode 100644 index 00000000..32de0bdf --- /dev/null +++ b/MVMCoreUI/Containers/NavigationController/UINavigationController+Extension.swift @@ -0,0 +1,87 @@ +// +// UINavigationController+Extension.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 3/14/22. +// Copyright © 2022 Verizon Wireless. All rights reserved. +// + +import Foundation + +public extension UINavigationController { + + /// Convenience function for setting the navigation item. + func setNavigationItem(with model: NavigationItemModelProtocol, for viewController: UIViewController) { + viewController.navigationItem.title = model.title + viewController.navigationItem.accessibilityLabel = model.title + viewController.navigationItem.hidesBackButton = model.hidesSystemBackButton + viewController.navigationItem.leftItemsSupplementBackButton = !model.hidesSystemBackButton + setNavigationButtons(with: model, for: viewController) + setNavigationTitleView(with: model, for: viewController) + } + + /// Convenience function for setting the navigation buttons. + func setNavigationButtons(with model: NavigationItemModelProtocol, for viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + var leftItems: [UIBarButtonItem] = [] + if model.hidesSystemBackButton, + model.alwaysShowBackButton != false { + if let backButtonModel = model.backButton, + MVMCoreNavigationHandler.shared()?.getViewControllers(for: self)?.count ?? 0 > 1 || model.alwaysShowBackButton ?? false { + leftItems.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + } + if let leftItemModels = model.additionalLeftButtons { + for item in leftItemModels { + leftItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + } + } + } + viewController.navigationItem.leftBarButtonItems = leftItems.count > 0 ? leftItems : nil + + var rightItems: [UIBarButtonItem] = [] + if let rightItemModels = model.additionalRightButtons { + for item in rightItemModels { + rightItems.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) + } + } + viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil + } + + /// Convenience function for setting the navigation titleView. + func setNavigationTitleView(with model: NavigationItemModelProtocol, for viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + if let titleViewModel = model.titleView, + let molecule = ModelRegistry.createMolecule(titleViewModel, delegateObject: delegate, additionalData: nil) { + viewController.navigationItem.titleView = molecule + } + } + + /// Returns a ShadowImage based on the line property of NavigationItemModelProtocol + func getNavigationBarShadowImage(for navigationItemModel: NavigationItemModelProtocol) -> UIImage? { + guard let thickness = navigationItemModel.line?.thickness, + let backgroundColor = navigationItemModel.line?.backgroundColor else { return nil } + return backgroundColor.uiColor.image(CGSize(width: thickness, height: thickness)) + } + + /// Convenience function for setting the navigation bar ui + func setNavigationBarUI(with model: NavigationItemModelProtocol) { + let navigationBar = navigationBar + let font = MFStyler.fontBoldBodySmall(false) + let backgroundColor = model.backgroundColor?.uiColor + let tint = model.tintColor.uiColor + navigationBar.tintColor = tint + + let appearance = UINavigationBarAppearance() + appearance.configureWithOpaqueBackground() + appearance.titleTextAttributes = [NSAttributedString.Key.font: font, + NSAttributedString.Key.foregroundColor: tint]; + appearance.backgroundColor = backgroundColor + appearance.titleTextAttributes.updateValue(tint, forKey: .foregroundColor) + appearance.shadowColor = model.line?.backgroundColor?.uiColor ?? .clear + appearance.shadowImage = getNavigationBarShadowImage(for: model)?.withRenderingMode(.alwaysTemplate) + navigationBar.standardAppearance = appearance + navigationBar.scrollEdgeAppearance = appearance + + setNavigationBarHidden(model.hidden, animated: true) + } +} diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift index a4bbcb08..c46a6bb6 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController+Extension.swift @@ -12,18 +12,13 @@ import Foundation public extension MVMCoreUISplitViewController { /// Convenience function. Sets the navigation and split view properties for the view controller. Panel access is determined if view controller is a detail view protocol. - static func setNavigationBarUI(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) { - guard let splitView = MVMCoreUISplitViewController.main(), - navigationController == splitView.navigationController, - viewController == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() else { + func setNavigationBar(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) { + guard navigationController == self.navigationController, + viewController == getCurrentDetailViewController() else { /// Not the split view navigation controller, skip split functions. return } - splitView.set(for: viewController, navigationController: navigationController, navigationItemModel: navigationItemModel) - } - - /// Sets the navigation item for the view controller based on the model and splitview controller - private func set(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) { + setLeftPanelIsAccessible((viewController as? MVMCoreUIDetailViewProtocol)?.isLeftPanelAccessible?() ?? false, for: viewController, updateNavigationButtons: false) setRightPanelIsAccessible((viewController as? MVMCoreUIDetailViewProtocol)?.isRightPanelAccessible?() ?? false, for: viewController, updateNavigationButtons: false) @@ -121,7 +116,7 @@ public extension MVMCoreUISplitViewController { guard let navigationController = navigationController, navigationController.isDisplayed(viewController: viewController), let model = navigationController.getNavigationModel(from: viewController) else { return } - set(for: viewController, navigationController: navigationController, navigationItemModel: model) + setNavigationBar(for: viewController, navigationController: navigationController, navigationItemModel: model) } } diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index c33d0238..c3be1868 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -78,7 +78,6 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, if let controller = viewController as? (UIViewController & MVMCoreViewManagerViewControllerProtocol) { MVMCoreViewManagerViewControllerProtocolHelper.helpSetManager(self, viewController: controller) } - hideNavigationBarLine(for: viewController) } required public init?(coder: NSCoder) { @@ -111,16 +110,27 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } } + open override func pageShown() { + // Currently not calling super until we can decouple page shown logics for managers. + hideNavigationBarLine(true) + } + open override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - // Notify showing view we will disappear. (viewController as? MVMCoreViewManagerViewControllerProtocol)?.managerWillDisappear?(self) } - /// Hides the navigation bar for the page. - open func hideNavigationBarLine(for viewController: UIViewController) { - (viewController as? PageProtocol)?.pageModel?.navigationBar?.line?.type = .none + /// Hides/Shows the navigation bar for the page. + open func hideNavigationBarLine(_ isHidden: Bool) { + guard self == navigationController?.topViewController else { return } + var color = UIColor.clear + if !isHidden, + let backgroundColor = (getCurrentViewController() as? PageProtocol)?.pageModel?.navigationBar?.line?.backgroundColor?.uiColor { + color = backgroundColor + } + navigationController?.navigationBar.standardAppearance.shadowColor = color + navigationController?.navigationBar.scrollEdgeAppearance?.shadowColor = color } open override func updateViews() { @@ -213,7 +223,6 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, index != tabs.selectedIndex else { return } viewController = controller pageType = (viewController as? MVMCoreViewControllerProtocol)?.pageType - hideNavigationBarLine(for: controller) if let viewController = getCurrentViewController() { manager?.willDisplay?(viewController) } @@ -253,6 +262,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, if let viewController = getCurrentViewController() { manager?.displayedViewController?(viewController) } + hideNavigationBarLine(true) } // MARK: - TabsDelegate @@ -279,6 +289,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, // MARK: - MVMCoreViewManagerViewControllerProtocol open override func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) { + super.viewControllerReady(inManager: manager) // Pass on down (viewController as? MVMCoreViewManagerViewControllerProtocol)?.viewControllerReady?(inManager: self) } @@ -297,19 +308,17 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } open func newDataReceived(in viewController: UIViewController) { - if viewController == self.viewController { - hideNavigationBarLine(for: viewController) - } manager?.newDataReceived?(in: viewController) + hideNavigationBarLine(true) } public func willDisplay(_ viewController: UIViewController) { - hideNavigationBarLine(for: viewController) manager?.willDisplay?(viewController) } public func displayedViewController(_ viewController: UIViewController) { manager?.displayedViewController?(viewController) + hideNavigationBarLine(true) } // MARK: - MVMCoreUISwipeNavigationProtocol