From 07226731c08cc58783763791acab121ee988d730 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Wed, 9 Mar 2022 17:15:15 -0500 Subject: [PATCH] Line model contains style logic. Fix for subnav revert custom navigation bar for now --- MVMCoreUI.xcodeproj/project.pbxproj | 4 -- MVMCoreUI/Atomic/Atoms/Views/Line.swift | 59 ++++++---------- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 39 ++++++++++- .../NavigationBar/NavigationBar.swift | 39 ----------- .../NavigationBar/NavigationItemModel.swift | 2 +- .../NavigationItemModelProtocol.swift | 1 + .../BaseControllers/ViewController.swift | 1 + .../Containers/NavigationController.swift | 70 ++++++++++++------- .../SubNav/SubNavManagerController.swift | 21 ++++-- 9 files changed, 125 insertions(+), 111 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationBar.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a26f56e5..2b9c6711 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -272,7 +272,6 @@ 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 */; }; @@ -856,7 +855,6 @@ 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 = ""; }; - AF97288527D2BF63009DC250 /* NavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBar.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 = ""; }; @@ -1828,7 +1826,6 @@ children = ( D23EA7FC247EBB7500D60C34 /* Buttons */, D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */, - AF97288527D2BF63009DC250 /* NavigationBar.swift */, ); path = NavigationBar; sourceTree = ""; @@ -2743,7 +2740,6 @@ 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 */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 22d33b1f..7985ec56 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: CGFloat(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..a9a29264 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 let backgroundColor = _backgroundColor { return backgroundColor } + if inverted { return backgroundColor_inverted } + 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/NavigationBar/NavigationBar.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationBar.swift deleted file mode 100644 index af748539..00000000 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationBar.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// 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.set(navigationBar: self, model: model) - line.setOptional(with: model.line, delegateObject, additionalData) - } -} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index dc2800b3..b7eaf2d8 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -22,7 +22,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc open var title: String? open var hidden = false - open var line = LineModel(type: .standard) + open var line: LineModel? = LineModel(type: .standard) open var hidesSystemBackButton = true open var style: NavigationItemStyle? diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 570581e5..8f82c946 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -13,6 +13,7 @@ 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 } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index d7e947db..4a154d3a 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -349,6 +349,7 @@ import UIKit } open func pageShown() { + guard self as? MVMCoreViewManagerProtocol == nil else { return } // Update split view properties if this is the current detail controller. if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() { MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 630edbca..21bc030b 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -10,12 +10,6 @@ import UIKit @objcMembers open class NavigationController: UINavigationController, MVMCoreViewManagerViewControllerProtocol { 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? { @@ -23,8 +17,8 @@ import UIKit } /// Sets up the application with a navigation controller - public static func setupNavigationController() -> NavigationController { - let navigationController = NavigationController(navigationBarClass: NavigationBar.self, toolbarClass: nil) + public static func setupNavigationController() -> Self? { + let navigationController = self.init() MVMCoreUISession.sharedGlobal()?.navigationController = navigationController MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController MVMCoreNavigationHandler.shared()?.navigationController = navigationController @@ -33,8 +27,8 @@ import UIKit } /// Sets up the application with a navigation controller as the main container. - public static func setupNavigationControllerAsMainController() -> NavigationController { - let navigationController = setupNavigationController() + public static func setupNavigationControllerAsMainController() -> Self? { + guard let navigationController = setupNavigationController() else { return nil } MVMCoreUISession.sharedGlobal()?.setup(asStandardLoadViewDelegate: navigationController) return navigationController } @@ -76,23 +70,39 @@ import UIKit viewController.navigationItem.rightBarButtonItems = rightItems.count > 0 ? rightItems : nil } + static 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)) + } +// let rect = CGRect(origin: .zero, size: size) +// UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0) +// color.setFill() +// UIRectFill(rect) +// let image = UIGraphicsGetImageFromCurrentImageContext() +// UIGraphicsEndImageContext() +// +// guard let cgImage = image?.cgImage else { return nil } +// self.init(cgImage: cgImage) +// +//// let pixelScale = UIScreen.main.scale +//// let pixelSize = thickness / pixelScale +//// let fillSize = CGSize(width: pixelSize, height: pixelSize) +//// let fillRect = CGRect(origin: CGPoint.zero, size: fillSize) +//// UIGraphicsBeginImageContextWithOptions(fillRect.size, false, pixelScale) +//// graphicsContext.setFillColor(backgroundColor.cgColor) +//// graphicsContext.fill(fillRect) +//// let image = UIGraphicsGetImageFromCurrentImageContext() +//// UIGraphicsEndImageContext() +// return image +// } + /// 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 { - set(navigationBar: navigationController.navigationBar, model: navigationItemModel) - } - navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) - } - - /// Convenience function for setting the navigation bar by the model - public static func set(navigationBar: UINavigationBar, model: NavigationItemModelProtocol) { let font = MFStyler.fontBoldBodySmall(false) - let backgroundColor = model.backgroundColor?.uiColor - let tint = model.tintColor.uiColor + let backgroundColor = navigationItemModel.backgroundColor?.uiColor + let tint = navigationItemModel.tintColor.uiColor navigationBar.tintColor = tint if #available(iOS 13.0, *) { let appearance = UINavigationBarAppearance() @@ -101,16 +111,19 @@ import UIKit NSAttributedString.Key.foregroundColor: tint]; appearance.backgroundColor = backgroundColor appearance.titleTextAttributes.updateValue(tint, forKey: .foregroundColor) + appearance.shadowColor = navigationItemModel.line?.backgroundColor?.uiColor ?? .clear + appearance.shadowImage = getNavigationBarShadowImage(for: navigationItemModel)?.withRenderingMode(.alwaysTemplate) navigationBar.standardAppearance = appearance navigationBar.scrollEdgeAppearance = appearance } else { // Fallback on earlier versions - navigationBar.shadowImage = UIImage() navigationBar.isOpaque = true + navigationBar.shadowImage = getNavigationBarShadowImage(for: navigationItemModel) navigationBar.titleTextAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: tint]; navigationBar.barTintColor = backgroundColor } + navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) } /// Convenience function for setting the navigation titleView. @@ -213,3 +226,12 @@ extension NavigationController: MVMCorePresentationDelegateProtocol { } } } + +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/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 2bcd2597..37a33ca9 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -110,22 +110,29 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, } } - open override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) + open override func pageShown() { + super.pageShown() hideNavigationBarLine(true) } open override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - hideNavigationBarLine(false) // Notify showing view we will disappear. (viewController as? MVMCoreViewManagerViewControllerProtocol)?.managerWillDisappear?(self) } /// Hides/Shows the navigation bar for the page. open func hideNavigationBarLine(_ isHidden: Bool) { - guard let navigationBar = navigationController?.navigationBar as? NavigationBar else { return } - navigationBar.line.isHidden = isHidden + guard self == navigationController?.topViewController else { return } + if #available(iOS 13.0, *) { + 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() { @@ -257,6 +264,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, if let viewController = getCurrentViewController() { manager?.displayedViewController?(viewController) } + hideNavigationBarLine(true) } // MARK: - TabsDelegate @@ -283,6 +291,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) } @@ -302,6 +311,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, open func newDataReceived(in viewController: UIViewController) { manager?.newDataReceived?(in: viewController) + hideNavigationBarLine(true) } public func willDisplay(_ viewController: UIViewController) { @@ -310,6 +320,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, public func displayedViewController(_ viewController: UIViewController) { manager?.displayedViewController?(viewController) + hideNavigationBarLine(true) } // MARK: - MVMCoreUISwipeNavigationProtocol