From b83abf673ec686865c2aae9ed8f89e6f9dce2253 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 11:17:09 -0400 Subject: [PATCH 01/33] color and indicator inversion --- .../CarouselIndicator/BarsIndicatorView.swift | 18 +++++++++++------- .../CarouselIndicator/CarouselIndicator.swift | 18 +++++++++++++++--- .../CarouselIndicatorModel.swift | 8 ++++++++ MVMCoreUI/Categories/UIColor+Extension.swift | 8 ++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift index 972ea7ca..9dc4a0bd 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/BarsIndicatorView.swift @@ -68,12 +68,7 @@ open class BarsIndicatorView: CarouselIndicator { get { return super.indicatorColor } set (newColor) { super.indicatorColor = newColor - - if isEnabled { - for (i, barTuple) in barReferences.enumerated() { - barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : newColor - } - } + refreshBarColors(with: newColor) } } @@ -102,6 +97,15 @@ open class BarsIndicatorView: CarouselIndicator { // MARK: - Methods //-------------------------------------------------- + private func refreshBarColors(with color: UIColor) { + + if isEnabled { + for (i, barTuple) in barReferences.enumerated() { + barTuple.view.backgroundColor = i == currentIndex ? currentIndicatorColor : color + } + } + } + func generateBars() { var bars = [(View, NSLayoutConstraint)]() @@ -142,7 +146,7 @@ open class BarsIndicatorView: CarouselIndicator { guard let model = model as? BarsCarouselIndicatorModel else { return } - currentIndicatorColor = model.currentIndicatorColor.uiColor + currentIndicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.currentIndicatorColor.uiColor } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift index 9380e8c0..e202a212 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift @@ -78,8 +78,20 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { } public var indicatorColor: UIColor { - get { return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack } - set { carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) } + get { + if let model = carouselIndicatorModel, model.inverted { + return carouselIndicatorModel?.indicatorColor_inverted.uiColor ?? .mvmWhite + } else { + return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack + } + } + set { + if let model = carouselIndicatorModel, model.inverted { + carouselIndicatorModel?.indicatorColor_inverted = Color(uiColor: newValue) + } else { + carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) + } + } } var accessibilityValueFormat: String? { @@ -191,7 +203,7 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { guard let model = model as? CarouselIndicatorModel else { return } - indicatorColor = model.indicatorColor.uiColor + indicatorColor = model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor disabledIndicatorColor = model.disabledIndicatorColor.uiColor currentIndex = model.currentIndex isEnabled = model.enabled diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index a0ac2273..359fe98a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -26,11 +26,13 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro public var currentIndex: Int = 0 public var animated: Bool = true public var hidesForSinglePage: Bool = false + public var inverted: Bool = false /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false public var accessibilityHasSlidesInsteadOfPage: Bool = false public var enabled: Bool = true public var disabledIndicatorColor: Color = Color(uiColor: .mvmCoolGray3) public var indicatorColor: Color = Color(uiColor: .mvmBlack) + public var indicatorColor_inverted: Color = Color(uiColor: .mvmWhite) public var position: Float? /// Allows sendActions() to trigger even if index is already at min/max index. @@ -53,6 +55,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro case disabledIndicatorColor case indicatorColor case position + case inverted } //-------------------------------------------------- @@ -72,6 +75,10 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro self.alwaysSendAction = alwaysSendAction } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + if let position = try typeContainer.decodeIfPresent(Float.self, forKey: .position) { self.position = position } @@ -112,6 +119,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro try container.encode(hidesForSinglePage, forKey: .hidesForSinglePage) try container.encode(accessibilityHasSlidesInsteadOfPage, forKey: .accessibilityHasSlidesInsteadOfPage) try container.encode(enabled, forKey: .enabled) + try container.encode(inverted, forKey: .inverted) try container.encode(disabledIndicatorColor, forKey: .disabledIndicatorColor) try container.encode(indicatorColor, forKey: .indicatorColor) try container.encodeIfPresent(position, forKey: .position) diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 1ef2e217..2ca287d1 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -34,6 +34,7 @@ extension UIColor { "green33": (.mvmGreen33, "#ABE4BF"), "green66": (.mvmGreen66, "#57C880"), "greenShade2": (.mvmGreenShade2, "#0F5B25"), + "greenInverted": (.mvmGreenInverted, "#00AC3E"), "orange": (.mvmOrange, "#ED7000"), "orange66": (.mvmOrange66, "#F3A157"), "orange33": (.mvmOrange33, "#F9D0AB"), @@ -45,6 +46,7 @@ extension UIColor { "blue66": (.mvmBlue66, "#57B1DF"), "blueShade1": (.mvmBlueShade1, "#136598"), "blueShade2": (.mvmBlueShade2, "#0B4467"), + "blueInverted": (.mvmBlueInverted, "#0088CE"), "yellow": (.mvmYellow, "#FFBC3D"), "coolGray1": (.mvmCoolGray1, "#F6F6F6"), "coolGray3": (.mvmCoolGray3, "#D8DADA"), @@ -147,6 +149,9 @@ extension UIColor { /// HEX: #0F5B25 public static let mvmGreenShade2 = UIColor.color8Bits(red: 15, green: 91, blue: 37) + /// HEX: #00AC3E + public static let mvmGreenInverted = UIColor.color8Bits(red: 0, green: 172, blue: 62) + //-------------------------------------------------- // MARK: - Blue //-------------------------------------------------- @@ -166,6 +171,9 @@ extension UIColor { /// HEX: #0B4467 public static let mvmBlueShade2 = UIColor.color8Bits(red: 11, green: 68, blue: 103) + /// HEX: #0088CE + public static let mvmBlueInverted = UIColor.color8Bits(red: 0, green: 136, blue: 206) + //-------------------------------------------------- // MARK: - Yellow //-------------------------------------------------- From 1a2d7b2abd3b45b2e4f8e2e6a50bf551279fb83f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 11:50:47 -0400 Subject: [PATCH 02/33] arrow color inversion --- MVMCoreUI/Atomic/Atoms/Views/Arrow.swift | 16 ++++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift | 7 +++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift index ea5023c8..0a3e0457 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift @@ -41,8 +41,20 @@ open class Arrow: View { } open var color: UIColor { - get { return arrowModel?.color.uiColor ?? .mvmBlack } - set { arrowModel?.color = Color(uiColor: newValue) } + get { + if let model = arrowModel, model.inverted { + return arrowModel?.color_inverted.uiColor ?? .mvmWhite + } else { + return arrowModel?.color.uiColor ?? .mvmBlack + } + } + set { + if let model = arrowModel, model.inverted { + arrowModel?.color_inverted = Color(uiColor: newValue) + } else { + arrowModel?.color = Color(uiColor: newValue) + } + } } open var degrees: Float { diff --git a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift index ac2b2d90..35dbd906 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift @@ -22,11 +22,13 @@ open class ArrowModel: MoleculeModelProtocol { public var backgroundColor: Color? public var disabledColor: Color = Color(uiColor: .mvmCoolGray3) public var color: Color = Color(uiColor: .mvmBlack) + public var color_inverted: Color = Color(uiColor: .mvmWhite) public var degrees: Float = 0 public var lineWidth: CGFloat = 1 public var height: CGFloat = 12 public var width: CGFloat = 12 public var enabled: Bool = true + public var inverted: Bool = false //-------------------------------------------------- // MARK: - Enum @@ -64,6 +66,7 @@ open class ArrowModel: MoleculeModelProtocol { case height case width case enabled + case inverted } //-------------------------------------------------- @@ -79,6 +82,10 @@ open class ArrowModel: MoleculeModelProtocol { self.disabledColor = disabledColor } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { self.color = color } From a093d4ec74774cd2fdee1f6929059463363fe82b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 12 May 2020 12:45:53 -0400 Subject: [PATCH 03/33] caret view inversion start --- MVMCoreUI/Atomic/Atoms/Views/CaretView.swift | 25 +++++++++--------- .../Atomic/Atoms/Views/CaretViewModel.swift | 26 +++++++++++++++++-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift index 93874287..86e8321c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift @@ -13,14 +13,14 @@ open class CaretView: View { //------------------------------------------------------ private var caretPath: UIBezierPath = UIBezierPath() - public var strokeColor: UIColor = .black + public var strokeColor: UIColor = .mvmBlack public var lineWidth: CGFloat = 1 public var direction: Direction = .right public var size: CaretSize? - public var enabledColor: UIColor = .black - public var disabledColor: UIColor = .mfSilver() + public var enabledColor: UIColor = .mvmBlack + public var disabledColor: UIColor = .mvmCoolGray3 //------------------------------------------------------ // MARK: - Property Observer @@ -161,7 +161,7 @@ open class CaretView: View { isOpaque = false isHidden = false backgroundColor = .clear - strokeColor = .black + strokeColor = .mvmBlack } /// Ensure you have defined a CaretSize with Orientation before calling. @@ -177,7 +177,7 @@ open class CaretView: View { // MARK: - Atomization //------------------------------------------------------ - // Default values for view. + /// Default values for view. public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.init(frame: .zero) defaultState() @@ -186,20 +186,21 @@ open class CaretView: View { override public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let caretModel = model as? CaretViewModel else { - return - } - strokeColor = caretModel.strokeColor.uiColor - isHidden = caretModel.isHidden ?? false - isOpaque = caretModel.isOpaque ?? false + + guard let model = model as? CaretViewModel else { return } + + strokeColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor + isHidden = model.isHidden ?? false + isOpaque = model.isOpaque ?? false - if let lineWidthValue = caretModel.lineWidth { + if let lineWidthValue = model.lineWidth { lineWidth = lineWidthValue } } } extension CaretView: MVMCoreUIViewConstrainingProtocol { + open func needsToBeConstrained() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index cf90496f..5bcfe092 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -8,15 +8,25 @@ import Foundation -@objcMembers public class CaretViewModel: MoleculeModelProtocol { +@objcMembers public class CaretViewModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "caretView" public var backgroundColor: Color? - public var strokeColor: Color = Color(uiColor: .black) + public var strokeColor: Color = Color(uiColor: .mvmBlack) + public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) public var isHidden: Bool? public var isOpaque: Bool? + public var inverted: Bool = false public var lineWidth: CGFloat? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor @@ -24,13 +34,24 @@ import Foundation case isHidden case isOpaque case lineWidth + case inverted } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) { self.strokeColor = strokeColor } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) @@ -41,6 +62,7 @@ import Foundation var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) + try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(isHidden, forKey: .isHidden) try container.encodeIfPresent(isOpaque, forKey: .isOpaque) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) From e676d78eb2294d9b88ec6f580656791fc9d0bb14 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 11:19:13 -0400 Subject: [PATCH 04/33] current state --- MVMCoreUI/Atomic/Atoms/Views/CaretView.swift | 26 +++++++++---------- .../Atomic/Atoms/Views/CaretViewModel.swift | 21 ++++++++++++--- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift index 86e8321c..20023091 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretView.swift @@ -13,7 +13,6 @@ open class CaretView: View { //------------------------------------------------------ private var caretPath: UIBezierPath = UIBezierPath() - public var strokeColor: UIColor = .mvmBlack public var lineWidth: CGFloat = 1 public var direction: Direction = .right @@ -28,7 +27,7 @@ open class CaretView: View { public var isEnabled: Bool = true { didSet { - strokeColor = isEnabled ? enabledColor : disabledColor + guard isEnabled != oldValue else { return } setNeedsDisplay() } } @@ -49,7 +48,7 @@ open class CaretView: View { case horizontal } - // Dimensions of container; provided by InVision design. + /// Dimensions of container; provided by InVision design. func dimensions() -> CGSize { switch self { @@ -92,7 +91,7 @@ open class CaretView: View { //------------------------------------------------------ @objc override open func setupView() { - + super.setupView() defaultState() } @@ -141,7 +140,7 @@ open class CaretView: View { caretPath.addLine(to: CGPoint(x: frame.size.width - inset, y: frame.size.height - inset)) } - strokeColor.setStroke() + enabledColor.setStroke() caretPath.stroke() } @@ -151,17 +150,16 @@ open class CaretView: View { @objc public func setLineColor(_ color: UIColor) { - strokeColor = color + enabledColor = color setNeedsDisplay() } @objc public func defaultState() { - translatesAutoresizingMaskIntoConstraints = false isOpaque = false isHidden = false backgroundColor = .clear - strokeColor = .mvmBlack + enabledColor = .mvmBlack } /// Ensure you have defined a CaretSize with Orientation before calling. @@ -178,7 +176,7 @@ open class CaretView: View { //------------------------------------------------------ /// Default values for view. - public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.init(frame: .zero) defaultState() set(with: model, delegateObject, additionalData) @@ -189,12 +187,12 @@ open class CaretView: View { guard let model = model as? CaretViewModel else { return } - strokeColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor - isHidden = model.isHidden ?? false - isOpaque = model.isOpaque ?? false - + enabledColor = (model.inverted ? model.strokeColor_inverted : model.strokeColor).uiColor + isHidden = model.isHidden + isOpaque = model.isOpaque + if let lineWidthValue = model.lineWidth { - lineWidth = lineWidthValue + lineWidth = lineWidthValue } } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index 5bcfe092..9dc43286 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -18,8 +18,8 @@ import Foundation public var backgroundColor: Color? public var strokeColor: Color = Color(uiColor: .mvmBlack) public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) - public var isHidden: Bool? - public var isOpaque: Bool? + public var isHidden: Bool = false + public var isOpaque: Bool = false public var inverted: Bool = false public var lineWidth: CGFloat? @@ -31,6 +31,7 @@ import Foundation case moleculeName case backgroundColor case strokeColor + case strokeColor_inverted case isHidden case isOpaque case lineWidth @@ -48,13 +49,24 @@ import Foundation self.strokeColor = strokeColor } + if let strokeColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor_inverted) { + self.strokeColor_inverted = strokeColor_inverted + } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { self.inverted = inverted } backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) - isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) + + if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) { + self.isHidden = isHidden + } + + if let isOpaque = try typeContainer.decodeIfPresent(Bool.self, forKey: .isOpaque) { + self.isOpaque = isOpaque + } + lineWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .lineWidth) } @@ -62,6 +74,7 @@ import Foundation var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) + try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted) try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(isHidden, forKey: .isHidden) try container.encodeIfPresent(isOpaque, forKey: .isOpaque) From 7b2d684c4e7c086481d3214e77da5d24f048e6d1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 14:25:45 -0400 Subject: [PATCH 05/33] changes for inversion --- .../Atomic/Atoms/Buttons/CaretLink.swift | 11 ++-- .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 44 ++++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 50 +++++++++++++------ 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift index d23a2606..0e2dfd7b 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift @@ -9,14 +9,13 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { - //------------------------------------------------------ // MARK: - Constants //------------------------------------------------------ private let CARET_VIEW_HEIGHT: Float = 10.5 private let CARET_VIEW_WIDTH: Float = 6.5 - + //------------------------------------------------------ // MARK: - Properties //------------------------------------------------------ @@ -82,7 +81,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { setTitleColor(enabledColor, for: .normal) setTitleColor(disabledColor, for: .disabled) - + if let rightCaretView = rightView as? CaretView { rightCaretView.enabledColor = enabledColor rightCaretView.disabledColor = disabledColor @@ -123,7 +122,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { bottomAnchor.constraint(greaterThanOrEqualTo: caretView.bottomAnchor).isActive = true contentHorizontalAlignment = .left - //set correct color after layout + // Set correct color after layout changeCaretColor() } @@ -135,6 +134,7 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { //------------------------------------------------------ // MARK: - Atomization //------------------------------------------------------ + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? CaretLinkModel else { return } @@ -143,7 +143,8 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { backgroundColor = color.uiColor } - enabledColor = model.enabledColor.uiColor + enabledColor = (model.inverted ? model.enabled_inverted : model.enabledColor).uiColor + if let color = model.disabledColor { disabledColor = color.uiColor } diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 8f3ee74d..5b48deea 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -9,46 +9,80 @@ import Foundation import MVMCore + public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "caretLink" public var backgroundColor: Color? public var title: String public var action: ActionModelProtocol - public var enabledColor: Color = Color(uiColor: .black) + public var enabledColor: Color = Color(uiColor: .mvmBlack) public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6) + public var enabled_inverted: Color = Color(uiColor: .mvmWhite) public var enabled = true - + public var inverted = false + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(title: String, action: ActionModelProtocol) { self.title = title self.action = action } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case backgroundColor case title case action + case enabled_inverted case enabledColor case disabledColor case enabled + case inverted case moleculeName } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) + + if let enabled_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabled_inverted) { + self.enabled_inverted = enabled_inverted + } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { enabledColor = color } + if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { disabledColor = color } + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { self.enabled = enabled } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + action = try typeContainer.decodeModel(codingKey: .action) } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) @@ -58,5 +92,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(enabled, forKey: .enabledColor) try container.encodeIfPresent(disabledColor, forKey: .disabledColor) try container.encode(enabled, forKey: .enabled) + try container.encode(enabled_inverted, forKey: .enabled_inverted) + try container.encode(inverted, forKey: .inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 7412230d..dbd1727e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -9,13 +9,16 @@ import UIKit @objcMembers public class LineModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- - /* - The frequency of the line in a moleculeList. - all (between all cells, above top, below bottom) - allExceptTop (between all cells, below bottom) - allExceptBottom (between all cells, above top) - between (between all cells) + /** + The frequency of the line in a moleculeList: + - all (between all cells, above top, below bottom) + - allExceptTop (between all cells, below bottom) + - allExceptBottom (between all cells, above top) + - between (between all cells) */ public enum Frequency: String, Codable { case all @@ -24,13 +27,13 @@ import UIKit case between } - /* - The style of the line. - standard (1 height, silver) - thin (1 height, black) - medium (2 height, black) - heavy (4 height, black) - none (hidden) + /** + The style of the line: + - standard (1 height, silver) + - thin (1 height, black) + - medium (2 height, black) + - heavy (4 height, black) + - none (hidden) */ public enum Style: String, Codable { case standard @@ -40,23 +43,35 @@ import UIKit case none } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "line" public var type: Style = .standard public var frequency: Frequency? = .allExceptTop //TODO: use color insted of backgroundColor. Needs server changes -// public var color: Color? + // public var color: Color? public var backgroundColor: Color? // Use this to show vertical line // Default is false public var useVerticalLine: Bool? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(type: Style) { self.type = type self.useVerticalLine = false } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case type @@ -66,14 +81,21 @@ import UIKit case useVerticalLine } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) { self.type = type } + if let frequency = try typeContainer.decodeIfPresent(Frequency.self, forKey: .frequency) { self.frequency = frequency } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine) } From 59288c8fdf934988cd4eb6a81aa480563c910e28 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 13 May 2020 17:12:51 -0400 Subject: [PATCH 06/33] latest inversion --- MVMCoreUI/Atomic/Atoms/Views/DashLine.swift | 28 +++++------ .../Atomic/Atoms/Views/DashLineModel.swift | 36 ++++++++++++-- MVMCoreUI/Atomic/Atoms/Views/Line.swift | 46 ++++++++++++++---- MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 47 ++++++++++++------- 4 files changed, 114 insertions(+), 43 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift index 86d2fd61..c8a59c6d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLine.swift @@ -18,10 +18,10 @@ open class DashLine: View { var dashModel: DashLineModel? { get { return model as? DashLineModel } } - + //TODO: Need this for BAU. Can remove once we fix BAU public var dashColor: UIColor? - + @objc private var dashLayer: CAShapeLayer? //------------------------------------------------------ @@ -65,15 +65,15 @@ open class DashLine: View { path.addLine(to: CGPoint(x: dashLayer.frame.size.width, y: 0)) path.stroke() - dashLayer.strokeStart = 0.0 + dashLayer.strokeStart = 0 dashLayer.lineWidth = 1 dashLayer.lineJoin = .miter dashLayer.lineCap = .round dashLayer.lineDashPattern = [NSNumber(value: 2), NSNumber(value: 2)] dashLayer.path = path.cgPath - dashLayer.strokeColor = dashModel?.dashColor.cgColor ?? dashColor?.cgColor + dashLayer.strokeColor = dashColor?.cgColor dashLayer.fillColor = UIColor.clear.cgColor - dashLayer.backgroundColor = backgroundColor?.cgColor ?? UIColor.white.cgColor + dashLayer.backgroundColor = (dashModel?.inverted ?? false) ? UIColor.mvmBlack.cgColor : backgroundColor?.cgColor ?? UIColor.mvmWhite.cgColor self.dashLayer = dashLayer } @@ -81,21 +81,21 @@ open class DashLine: View { // MARK: - Atomization //------------------------------------------------------ - // Default values for view. @objc open override func reset() { - backgroundColor = .clear + super.reset() + isHidden = false } public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let dashLineModel = dashModel else { - return - } - if let isHiddenValue = dashLineModel.isHidden { - isHidden = isHiddenValue - } - if let backgroundColor = dashLineModel.backgroundColor { + + guard let model = dashModel else { return } + + isHidden = model.isHidden + dashColor = (model.inverted ? model.dashColor_inverted : model.dashColor).uiColor + + if let backgroundColor = model.backgroundColor { dashLayer?.backgroundColor = backgroundColor.uiColor.cgColor } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift index 7f5ac992..523d83a6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift @@ -8,38 +8,66 @@ import Foundation + @objcMembers public class DashLineModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "dashLine" public var backgroundColor: Color? + public var dashColor: Color = Color(uiColor: .mvmCoolGray3) + public var dashColor_inverted: Color = Color(uiColor: .mvmWhite) + public var isHidden: Bool = false + public var inverted: Bool = false - public var dashColor: Color = Color(uiColor: .mfLighterGray()) - public var isHidden: Bool? + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- public init(dashColor: Color) { self.dashColor = dashColor } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor + case dashColor_inverted case dashColor case isHidden } + + //-------------------------------------------------- + // MARK: - codec + //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let dashColor = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor) { self.dashColor = dashColor } + + if let dashColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor_inverted) { + self.dashColor_inverted = dashColor_inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) + + if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) { + self.isHidden = isHidden + } } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(dashColor, forKey: .dashColor) - try container.encodeIfPresent(isHidden, forKey: .isHidden) + try container.encode(isHidden, forKey: .isHidden) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 42043c8f..d0890540 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -8,14 +8,27 @@ import UIKit + @objcMembers open class Line: View { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + var lineModel: LineModel? { get { return model as? LineModel } } + var lineBackgroundColor: Color? { + return (lineModel?.inverted ?? false) ? lineModel?.backgroundColor_inverted : lineModel?.backgroundColor + } + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + public var heightConstraint: NSLayoutConstraint? public var widthConstraint: NSLayoutConstraint? - + open func updateLineConstraints(constant: CGFloat) { if let useVerticalLine = lineModel?.useVerticalLine, useVerticalLine { heightConstraint?.isActive = false @@ -28,7 +41,23 @@ import UIKit } } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + + public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { + self.init(frame: .zero) + + view.addSubview(self) + NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + open func setStyle(_ style: LineModel.Style) { + switch style { case .standard: updateLineConstraints(constant: 1) @@ -47,21 +76,18 @@ import UIKit } } - // MARK: - Helpers open func shouldBeVisible() -> Bool { guard let type = lineModel?.type else { return false } return type != .none } - public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { - self.init(frame: .zero) - view.addSubview(self) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) - } + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol + //-------------------------------------------------- - // MARK: - MVMCoreViewProtocol open override func setupView() { super.setupView() + heightConstraint = heightAnchor.constraint(equalToConstant: 1) heightConstraint?.isActive = true widthConstraint = widthAnchor.constraint(equalToConstant: 1) @@ -69,9 +95,9 @@ import UIKit setStyle(.standard) } - // MARK: - MoleculeViewProtocol open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + if let lineModel = model as? LineModel { setStyle(lineModel.type) } @@ -82,7 +108,9 @@ 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 diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index dbd1727e..8a245066 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -8,18 +8,19 @@ import UIKit + @objcMembers public class LineModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- /** - The frequency of the line in a moleculeList: - - all (between all cells, above top, below bottom) - - allExceptTop (between all cells, below bottom) - - allExceptBottom (between all cells, above top) - - between (between all cells) - */ + The frequency of the line in a moleculeList: + - all (between all cells, above top, below bottom) + - allExceptTop (between all cells, below bottom) + - allExceptBottom (between all cells, above top) + - between (between all cells) + */ public enum Frequency: String, Codable { case all case allExceptTop @@ -28,13 +29,13 @@ import UIKit } /** - The style of the line: - - standard (1 height, silver) - - thin (1 height, black) - - medium (2 height, black) - - heavy (4 height, black) - - none (hidden) - */ + The style of the line: + - standard (1 height, silver) + - thin (1 height, black) + - medium (2 height, black) + - heavy (4 height, black) + - none (hidden) + */ public enum Style: String, Codable { case standard case thin @@ -50,10 +51,12 @@ import UIKit public static var identifier: String = "line" public var type: Style = .standard public var frequency: Frequency? = .allExceptTop - + //TODO: use color insted of backgroundColor. Needs server changes // public var color: Color? public var backgroundColor: Color? + public var backgroundColor_inverted: Color = Color(uiColor: .mvmWhite) + public var inverted: Bool = false // Use this to show vertical line // Default is false @@ -76,15 +79,17 @@ import UIKit case moleculeName case type case backgroundColor + case backgroundColor_inverted case color case frequency + case inverted case useVerticalLine } //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -96,14 +101,24 @@ import UIKit self.frequency = frequency } + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + + if let backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted) { + + self.backgroundColor_inverted = backgroundColor_inverted + } + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) useVerticalLine = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalLine) } - + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) 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(useVerticalLine, forKey: .useVerticalLine) From e9a9c953736f12daf45a13978caaca97a5f6c4b2 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 14 May 2020 15:02:19 -0400 Subject: [PATCH 07/33] inversion colors --- .../Atoms/Buttons/Link/ExternalLink.swift | 2 +- .../Buttons/Link/ExternalLinkModel.swift | 1 + .../Atomic/Atoms/Buttons/Link/Link.swift | 16 ++- .../Atomic/Atoms/Buttons/Link/LinkModel.swift | 32 ++++- .../Atomic/Atoms/Selectors/Checkbox.swift | 42 +++--- .../Atoms/Selectors/CheckboxModel.swift | 130 +++++++++++++----- .../RadioButtonLabel.swift | 5 +- .../RadioButtonLabelModel.swift | 5 + 8 files changed, 166 insertions(+), 67 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift index c65698c3..e051cf32 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLink.swift @@ -25,7 +25,7 @@ open class ExternalLink: Link { guard let model = model as? ExternalLinkModel else { return } - exportImageView?.tintColor = model.enabledColor.uiColor + exportImageView?.tintColor = titleColor(for: model.enabled ? .normal : .disabled) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift index f492a546..19d6643c 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/ExternalLinkModel.swift @@ -8,6 +8,7 @@ import UIKit + open class ExternalLinkModel: LinkModel { override open class var identifier: String { diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift index 5f5e6e12..7413fcbb 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/Link.swift @@ -37,9 +37,7 @@ import UIKit } open override var intrinsicContentSize: CGSize { - guard let size = titleLabel?.intrinsicContentSize else { - return super.intrinsicContentSize - } + guard let size = titleLabel?.intrinsicContentSize else { return super.intrinsicContentSize } return CGSize(width: size.width, height: size.height + 2) } @@ -49,17 +47,18 @@ import UIKit public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) + guard let model = model as? LinkModel else { return } setTitle(model.title, for: .normal) - setTitleColor(model.enabledColor.uiColor, for: .normal) - setTitleColor(model.disabledColor.uiColor, for: .disabled) + setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal) + setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled) isEnabled = model.enabled set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 31.0 + return 31 } } @@ -68,12 +67,15 @@ extension Link { open override func updateView(_ size: CGFloat) { super.updateView(size) + DispatchQueue.main.async { [weak self] in guard let self = self else { return } + var width = size - if MVMCoreGetterUtility.fequal(a: Float(CGFloat.leastNormalMagnitude), b: Float(size)) { + if MVMCoreGetterUtility.fequal(a: Float.leastNormalMagnitude, b: Float(size)) { width = MVMCoreUIUtility.getWidth() } + self.titleLabel?.font = MFStyler.fontB2(forWidth: width) } } diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index a54f23e9..d51bddf4 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -8,6 +8,7 @@ import UIKit + open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties @@ -22,7 +23,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { public var action: ActionModelProtocol public var enabled = true public var enabledColor = Color(uiColor: .mvmBlack) + public var enabledColor_inverted = Color(uiColor: .mvmWhite) public var disabledColor = Color(uiColor: .mvmCoolGray6) + public var disabledColor_inverted = Color(uiColor: .mvmCoolGray10) + public var inverted = false //-------------------------------------------------- // MARK: - Initializer @@ -44,7 +48,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { case action case enabled case enabledColor + case enabledColor_inverted case disabledColor + case disabledColor_inverted + case inverted } //-------------------------------------------------- @@ -53,6 +60,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action) @@ -60,12 +68,25 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { self.enabled = enabled } - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { - enabledColor = color + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted } - if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { - disabledColor = color + if let enabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { + self.enabledColor = enabledColor + } + + if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) { + self.enabledColor_inverted = enabledColor_inverted + } + + if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { + self.disabledColor = disabledColor + } + + if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) { + self.disabledColor_inverted = disabledColor_inverted } } @@ -75,8 +96,11 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModel(action, forKey: .action) + try container.encode(inverted, forKey: .inverted) try container.encode(enabled, forKey: .enabled) try container.encode(enabledColor, forKey: .enabledColor) + try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted) try container.encode(disabledColor, forKey: .disabledColor) + try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift index cb404f5a..cffbb916 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift @@ -97,7 +97,7 @@ import MVMCore public var disabledCheckColor: UIColor = .mvmCoolGray3 /// Color of the check mark. - public var checkColor: UIColor = .black { + public var checkColor: UIColor = .mvmBlack { didSet { setShapeLayerStrokeColor(checkColor) } @@ -111,7 +111,7 @@ import MVMCore } /// border color of the Checkbox - public var borderColor: UIColor = .black { + public var borderColor: UIColor = .mvmBlack { didSet { layer.borderColor = borderColor.cgColor } @@ -126,7 +126,7 @@ import MVMCore didSet { if !updateSelectionOnly { layoutIfNeeded() - (model as? CheckboxModel)?.isChecked = isSelected + (model as? CheckboxModel)?.checked = isSelected shapeLayer?.removeAllAnimations() updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated) _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) @@ -375,10 +375,10 @@ import MVMCore shapeLayer?.removeFromSuperlayer() shapeLayer = nil backgroundColor = .clear - borderColor = .black - borderWidth = 1.0 - checkColor = .black - checkWidth = 2.0 + borderColor = .mvmBlack + borderWidth = 1 + checkColor = .mvmBlack + checkWidth = 2 checkAndBypassAnimations(selected: false) } @@ -393,32 +393,34 @@ import MVMCore public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? CheckboxModel else { return } self.delegateObject = delegateObject + + guard let model = model as? CheckboxModel else { return } + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) if let fieldKey = model.fieldKey { self.fieldKey = fieldKey } - borderColor = model.borderColor.uiColor + borderColor = (model.inverted ? model.invertedColor : model.borderColor).uiColor borderWidth = model.borderWidth - checkColor = model.checkColor.uiColor - unCheckedBackgroundColor = model.unCheckedBackgroundColor.uiColor - checkedBackgroundColor = model.checkedBackgroundColor.uiColor - disabledCheckColor = model.disabledCheckColor.uiColor - disabledBorderColor = model.disabledBorderColor.uiColor - disabledBackgroundColor = model.disabledBackgroundColor.uiColor + checkColor = (model.inverted ? model.invertedColor : model.checkColor).uiColor + unCheckedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.unCheckedBackgroundColor).uiColor + checkedBackgroundColor = (model.inverted ? model.invertedBackgroundColor : model.checkedBackgroundColor).uiColor + disabledCheckColor = (model.inverted ? model.invertedColor : model.disabledCheckColor).uiColor + disabledBorderColor = (model.inverted ? model.invertedColor : model.disabledBorderColor).uiColor + disabledBackgroundColor = (model.inverted ? model.invertedColor : model.disabledBackgroundColor).uiColor - isAnimated = model.isAnimated - isRound = model.isRound + isAnimated = model.animated + isRound = model.round - if model.isChecked { - checkAndBypassAnimations(selected: model.isChecked) + if model.checked { + checkAndBypassAnimations(selected: model.checked) } - isEnabled = model.isEnabled + isEnabled = model.enabled if let action = model.action { actionBlock = { diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 423ed1ee..43a08aa6 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -8,6 +8,7 @@ import Foundation + @objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- // MARK: - Properties @@ -15,20 +16,23 @@ import Foundation public static var identifier: String = "checkbox" public var backgroundColor: Color? - public var isChecked: Bool = false - public var isEnabled: Bool = true - public var isAnimated: Bool = true - public var isRound: Bool = false + public var checked: Bool = false + public var enabled: Bool = true + public var animated: Bool = true + public var inverted: Bool = false + public var round: Bool = false public var borderWidth: CGFloat = 1 - public var borderColor: Color = Color(uiColor: .black) - public var checkColor: Color = Color(uiColor: .black) + public var borderColor: Color = Color(uiColor: .mvmBlack) + public var checkColor: Color = Color(uiColor: .mvmBlack) public var unCheckedBackgroundColor: Color = Color(uiColor: .clear) public var checkedBackgroundColor: Color = Color(uiColor: .clear) public var disabledBackgroundColor: Color = Color(uiColor: .clear) public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3) public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3) + public var invertedColor: Color = Color(uiColor: .mvmWhite) + public var invertedBackgroundColor: Color = Color(uiColor: .mvmBlack) public var action: ActionModelProtocol? - + public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName public var baseValue: AnyHashable? @@ -39,13 +43,16 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName - case isChecked = "checked" - case isEnabled = "enabled" - case isAnimated = "animated" - case isRound = "round" + case checked + case enabled + case inverted + case animated + case round case borderWidth case borderColor case checkColor + case invertedColor + case invertedBackgroundColor case unCheckedBackgroundColor case checkedBackgroundColor case disabledBackgroundColor @@ -56,12 +63,20 @@ import Foundation case groupName } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public func formFieldValue() -> AnyHashable? { - return isChecked + return checked } + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + public init(isChecked: Bool = false) { - self.isChecked = isChecked + self.checked = isChecked baseValue = isChecked } @@ -71,22 +86,72 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1 - borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black) - checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black) - unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) ?? Color(uiColor: .clear) - checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) ?? Color(uiColor: .clear) - disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) ?? Color(uiColor: .clear) - disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) ?? Color(uiColor: .mvmCoolGray3) - disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) ?? Color(uiColor: .mvmCoolGray3) - isChecked = try typeContainer.decodeIfPresent(Bool.self, forKey: .isChecked) ?? false - isAnimated = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAnimated) ?? true - isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false - isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true - action = try typeContainer.decodeModelIfPresent(codingKey: .action) - baseValue = isChecked + if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { + self.borderWidth = borderWidth + } + + if let borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) { + self.borderColor = borderColor + } + + if let checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) { + self.checkColor = checkColor + } + + if let unCheckedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .unCheckedBackgroundColor) { + self.unCheckedBackgroundColor = unCheckedBackgroundColor + } + + if let checkedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkedBackgroundColor) { + self.checkedBackgroundColor = checkedBackgroundColor + } + + if let disabledBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBackgroundColor) { + self.disabledBackgroundColor = disabledBackgroundColor + } + + if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) { + self.disabledBorderColor = disabledBorderColor + } + + if let disabledCheckColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledCheckColor) { + self.disabledCheckColor = disabledCheckColor + } + + if let invertedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedColor) { + self.invertedColor = invertedColor + } + + if let invertedBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .invertedBackgroundColor) { + self.invertedBackgroundColor = invertedBackgroundColor + } + + if let checked = try typeContainer.decodeIfPresent(Bool.self, forKey: .checked) { + self.checked = checked + } + + baseValue = checked + + if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) { + self.animated = animated + } + + if let round = try typeContainer.decodeIfPresent(Bool.self, forKey: .round) { + self.round = round + } + + if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) { + self.inverted = inverted + } + + if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) { + self.enabled = enabled + } + + action = try typeContainer.decodeModelIfPresent(codingKey: .action) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { self.groupName = groupName } @@ -99,16 +164,19 @@ import Foundation try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(borderColor, forKey: .borderColor) try container.encode(borderWidth, forKey: .borderWidth) - try container.encode(isChecked, forKey: .isChecked) + try container.encode(checked, forKey: .checked) + try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(checkColor, forKey: .checkColor) + try container.encodeIfPresent(invertedColor, forKey: .invertedColor) + try container.encodeIfPresent(invertedBackgroundColor, forKey: .invertedBackgroundColor) try container.encodeIfPresent(unCheckedBackgroundColor, forKey: .unCheckedBackgroundColor) try container.encodeIfPresent(checkedBackgroundColor, forKey: .checkedBackgroundColor) try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor) try container.encodeIfPresent(disabledBackgroundColor, forKey: .disabledBackgroundColor) try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor) - try container.encodeIfPresent(isAnimated, forKey: .isAnimated) - try container.encodeIfPresent(isRound, forKey: .isRound) - try container.encodeIfPresent(isEnabled, forKey: .isEnabled) + try container.encodeIfPresent(animated, forKey: .animated) + try container.encodeIfPresent(round, forKey: .round) + try container.encodeIfPresent(enabled, forKey: .enabled) try container.encodeModelIfPresent(action, forKey: .action) try container.encodeIfPresent(groupName, forKey: .groupName) } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift index 91034095..d415971e 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabel.swift @@ -8,6 +8,7 @@ import UIKit + @objcMembers public class RadioButtonLabel: View { public let radioButton = RadioButton() @@ -35,9 +36,6 @@ import UIKit open override func setupView() { super.setupView() - guard subviews.count == 0 else { - return - } addSubview(radioButton) radioButton.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor, constant: 0).isActive = true @@ -72,5 +70,4 @@ import UIKit radioButton.set(with: radioButtonLabelModel.radioButton, delegateObject, additionalData) label.set(with: radioButtonLabelModel.label, delegateObject, additionalData) } - } diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index 62df9794..014030ce 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -8,7 +8,12 @@ import Foundation + @objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "radioButtonLabel" public var backgroundColor: Color? public var moleculeName: String From d476b9ce14a77354bfa174a2ee4c0074346601f2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 14:55:29 -0400 Subject: [PATCH 08/33] Navigation fixing --- MVMCoreUI.xcodeproj/project.pbxproj | 28 ++++++++++-- MVMCoreUI/Atomic/Atoms/Views/Line.swift | 4 ++ .../NavigationItemButtonModel.swift | 35 +++++++++++++++ .../NavigationItemModel.swift} | 43 +------------------ .../NavigationItemModelProtocol.swift | 21 +++++++++ .../PanelNavigationItemModelProtocol.swift | 14 ++++++ .../MVMControllerModelProtocol.swift | 1 + .../Containers/NavigationController.swift | 10 ++--- .../MVMCoreUISplitViewController.h | 4 +- .../MVMCoreUISplitViewController.m | 13 ++++-- 10 files changed, 116 insertions(+), 57 deletions(-) create mode 100644 MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift rename MVMCoreUI/Atomic/Molecules/{NavigationItemModelProtocol.swift => NavigationBar/NavigationItemModel.swift} (70%) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index ec7e68b0..59816653 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -245,7 +245,7 @@ D2092357244FA1EF0044AD09 /* ThreeLayerModelBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */; }; D20923592450ECE00044AD09 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20923582450ECE00044AD09 /* TableView.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; - D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */; }; + D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */; }; D21B7F71243BAC1600051ABF /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */; }; @@ -264,6 +264,9 @@ D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; + D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; + D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */; }; + D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; }; @@ -656,7 +659,7 @@ D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerModelBase.swift; sourceTree = ""; }; D20923582450ECE00044AD09 /* TableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableView.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; - D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; + D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModel.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; D21B7F5E2437C5BC00051ABF /* MoleculeStackView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = ""; }; D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewCell.swift; sourceTree = ""; }; @@ -675,6 +678,9 @@ D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; + D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; + D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; + D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; @@ -852,6 +858,8 @@ 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */, D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, + D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, + D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -1313,6 +1321,15 @@ path = TwoColumn; sourceTree = ""; }; + D2509ED42472EE0B001BFB9D /* NavigationBar */ = { + isa = PBXGroup; + children = ( + D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */, + D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */, + ); + path = NavigationBar; + sourceTree = ""; + }; D253BB9A24587023002DE544 /* OtherContainers */ = { isa = PBXGroup; children = ( @@ -1453,6 +1470,7 @@ D29DF10E21E67A77003B2FB9 /* Molecules */ = { isa = PBXGroup; children = ( + D2509ED42472EE0B001BFB9D /* NavigationBar */, D253BB9A24587023002DE544 /* OtherContainers */, D22B38E923F4E07800490EF6 /* DesignedComponents */, D22479912316A9EF003FCCF9 /* Items */, @@ -1466,7 +1484,6 @@ 012A88EB238F084D00FE3DA1 /* FooterModel.swift */, D274CA322236A78900B01B62 /* FooterView.swift */, D260105723CF9CC500764D80 /* Doughnut */, - D20FB164241A5D75004AFC3A /* NavigationItemModelProtocol.swift */, ); path = Molecules; sourceTree = ""; @@ -1920,6 +1937,7 @@ 8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */, 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, + D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, @@ -2119,8 +2137,10 @@ 014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */, + D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */, 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, + D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, @@ -2160,7 +2180,7 @@ D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, - D20FB165241A5D75004AFC3A /* NavigationItemModelProtocol.swift in Sources */, + D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */, AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */, DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */, D224798A2314445E003FCCF9 /* LabelToggle.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 62550503..d34aee06 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -55,6 +55,10 @@ import UIKit public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { self.init(frame: .zero) + addLine(to: view, edge: edge, useMargin: useMargin) + } + + open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) { view.addSubview(self) NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) } diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift new file mode 100644 index 00000000..9110bfe9 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -0,0 +1,35 @@ +// +// NavigationItemButtonModel.swift +// +// +// Created by Scott Pfeil on 5/18/20. +// + +import Foundation + +public class NavigationItemButtonModel: Codable { + var imageName: String + var action: ActionModelProtocol + + public init(with imageName: String, action: ActionModelProtocol) { + self.imageName = imageName + self.action = action + } + + private enum CodingKeys: String, CodingKey { + case imageName + case action + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + imageName = try typeContainer.decode(String.self, forKey: .imageName) + action = try typeContainer.decodeModel(codingKey: .action) + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(imageName, forKey: .imageName) + try container.encodeModel(action, forKey: .action) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift similarity index 70% rename from MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift rename to MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index f15a847a..50ae62d6 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -8,48 +8,7 @@ import Foundation -public protocol NavigationItemModelProtocol { - var title: String? { get set } - var hidden: Bool { get set } - var backgroundColor: Color? { get set } - var translucent: Bool { get set } - var tintColor: Color { get set } - var line: LineModel? { get set } - var showLeftPanelButton: Bool { get set } - var showRightPanelButton: Bool { get set } - var backButton: NavigationItemButtonModel? { get set } - var additionalLeftButtons: [NavigationItemButtonModel]? { get set } - var additionalRightButtons: [NavigationItemButtonModel]? { get set } -} - -public class NavigationItemButtonModel: Codable { - var imageName: String - var action: ActionModelProtocol - - public init(with imageName: String, action: ActionModelProtocol) { - self.imageName = imageName - self.action = action - } - - private enum CodingKeys: String, CodingKey { - case imageName - case action - } - - required public init(from decoder: Decoder) throws { - let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - imageName = try typeContainer.decode(String.self, forKey: .imageName) - action = try typeContainer.decodeModel(codingKey: .action) - } - - open func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(imageName, forKey: .imageName) - try container.encodeModel(action, forKey: .action) - } -} - -public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol { +public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationItemModelProtocol, MoleculeModelProtocol { public class var identifier: String { return "navigationBar" } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift new file mode 100644 index 00000000..634539d4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -0,0 +1,21 @@ +// +// NavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol NavigationItemModelProtocol { + var title: String? { get set } + var hidden: Bool { get set } + var backgroundColor: Color? { get set } + var translucent: Bool { get set } + var tintColor: Color { get set } + var line: LineModel? { get set } + var backButton: NavigationItemButtonModel? { get set } + var additionalLeftButtons: [NavigationItemButtonModel]? { get set } + var additionalRightButtons: [NavigationItemButtonModel]? { get set } +} diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift new file mode 100644 index 00000000..8f599be4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift @@ -0,0 +1,14 @@ +// +// PanelNavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PanelNavigationItemModelProtocol { + var showLeftPanelButton: Bool { get set } + var showRightPanelButton: Bool { get set } +} diff --git a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift index 579a612e..d6851d78 100644 --- a/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift +++ b/MVMCoreUI/BaseControllers/MVMControllerModelProtocol.swift @@ -5,6 +5,7 @@ // Created by Scott Pfeil on 3/16/20. // Copyright © 2020 Verizon Wireless. All rights reserved. // +// A convenience aggregate for common MVM templates. import Foundation diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index f278236c..3497075f 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -40,6 +40,7 @@ import UIKit return navigationController } + /// Convenience function for setting navigation bar with model. public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { viewController.navigationItem.title = navigationItemModel.title viewController.navigationItem.accessibilityLabel = navigationItemModel.title @@ -54,13 +55,12 @@ import UIKit // Have the navigation title match the tint color navigationController.navigationBar.titleTextAttributes?.updateValue(tint, forKey: .foregroundColor) - // Update icons if main navigation controller. - if navigationController == MVMCoreUISession.sharedGlobal()?.navigationController, - navigationController.topViewController == viewController { - // Update line. - MVMCoreUISession.sharedGlobal()?.navigationController?.separatorView?.setStyle(navigationItemModel.line?.type ?? .standard) + // Update line. + if let navigationController = navigationController as? NavigationController { + navigationController.separatorView?.setStyle(navigationItemModel.line?.type ?? .standard) } + // Update icons if main navigation controller. if navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController { // Update Panels diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h index 0c252a08..e70a8b8b 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.h @@ -124,8 +124,8 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) { - (nullable UIImage *)imageForBackButton; // Can overide to provide other global buttons to be on the navigation bar. -- (nullable NSArray *)additionalLeftButtons; -- (nullable NSArray *)additionalRightButtons; +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController; +- (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController; // The width of the panel when it is permanently extended. Default 320. - (CGFloat)leftPanelExtendedWidth; diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index e93ad613..f5c07d04 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -106,11 +106,16 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)additionalLeftButtons { +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { + return nil; + } + UIViewController *controller = (UIViewController *)viewController; + controller.page return nil; } -- (nullable NSArray *)additionalRightButtons { +- (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { return nil; } @@ -239,7 +244,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } - NSArray *extraButtons = [self additionalLeftButtons]; + NSArray *extraButtons = [self additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController]; if (extraButtons) { [leftBarButtonItems addObjectsFromArray:extraButtons]; } @@ -410,7 +415,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.rightPanelButton) { [navigationItems addObject:self.rightPanelButton]; } - NSArray *extraButtons = [self additionalRightButtons]; + NSArray *extraButtons = [self additionalRightButtonsForViewController:(nonnull UIViewController *)viewController]; if (extraButtons) { [navigationItems addObjectsFromArray:extraButtons]; } From cde8218e43db95b2b2d9b52fe54927eea91f1f80 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 21:10:50 -0400 Subject: [PATCH 09/33] navigation item button fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++-- .../NavigationBar/NavigationItemModel.swift | 6 +- .../PanelNavigationItemModelProtocol.swift | 14 ++++ MVMCoreUI/BaseClasses/BarButtonItem.swift | 71 ++++++++++++++++++- .../BaseControllers/ViewController.swift | 20 ++++-- .../Containers/NavigationController.swift | 9 ++- .../MVMCoreUISplitViewController.m | 31 +++++--- 7 files changed, 139 insertions(+), 24 deletions(-) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 7cd0c44e..0d6a0f45 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -269,9 +269,9 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; + D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; - D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */; }; D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; @@ -296,6 +296,7 @@ D268C70C2386DFFD007F2C1C /* MoleculeStackItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368A23609801006832FA /* MoleculeStackItemModel.swift */; }; D268C70E238C22D7007F2C1C /* DropDownFilterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */; }; D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */; }; + D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D272F5F82473163100BD1A8F /* BarButtonItem.swift */; }; D274CA332236A78900B01B62 /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* FooterView.swift */; }; D2755D7B23689C7500485468 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2755D7A23689C7500485468 /* TableViewCell.swift */; }; D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */; }; @@ -689,9 +690,9 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; + D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; - D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PanelNavigationItemModelProtocol.swift; sourceTree = ""; }; D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; @@ -715,6 +716,7 @@ D264FAAB2441009400D98315 /* RadioBoxCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioBoxCollectionViewCell.swift; sourceTree = ""; }; D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownFilterTableViewCell.swift; sourceTree = ""; }; D26C5A6A23F4A40D007AEECE /* ListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = ""; }; + D272F5F82473163100BD1A8F /* BarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarButtonItem.swift; sourceTree = ""; }; D274CA322236A78900B01B62 /* FooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterView.swift; sourceTree = ""; }; D2755D7A23689C7500485468 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsTableViewCell.swift; sourceTree = ""; }; @@ -871,7 +873,7 @@ D2E2A9A223E096B1000B42E6 /* DisableableModelProtocol.swift */, D2092354244FA0FD0044AD09 /* ThreeLayerTemplateModelProtocol.swift */, D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */, - D2509ED22472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift */, + D23EA7E72473654300D60C34 /* PanelNavigationItemModelProtocol.swift */, ); path = ModelProtocols; sourceTree = ""; @@ -1803,6 +1805,7 @@ D264FAA92440F97600D98315 /* CollectionView.swift */, 0A5D59C323AD488600EFD9E9 /* Protocols */, 0A7918F423F5E7EA00772FF4 /* ImageView.swift */, + D272F5F82473163100BD1A8F /* BarButtonItem.swift */, ); path = BaseClasses; sourceTree = ""; @@ -1988,6 +1991,7 @@ D21B7F602437C5BC00051ABF /* MoleculeStackView.swift in Sources */, 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */, AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */, + D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */, 0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */, D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */, 01004F3022721C3800991ECC /* RadioButton.swift in Sources */, @@ -2104,6 +2108,7 @@ 01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */, 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, + D23EA7E82473654300D60C34 /* PanelNavigationItemModelProtocol.swift in Sources */, 94F6516D2437954100631BF9 /* Tabs.swift in Sources */, 5248BFEC23F12E350059236A /* ListThreeColumnPlanDataDivider.swift in Sources */, 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */, @@ -2166,7 +2171,6 @@ D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */, 8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, - D2509ED32472EDC8001BFB9D /* PanelNavigationItemModelProtocol.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 50ae62d6..38dee0d2 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -19,12 +19,14 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public var translucent: Bool public var tintColor: Color public var line: LineModel? - public var showLeftPanelButton: Bool - public var showRightPanelButton: Bool public var backButton: NavigationItemButtonModel? public var additionalLeftButtons: [NavigationItemButtonModel]? public var additionalRightButtons: [NavigationItemButtonModel]? + // Legacy, will remove once menu is gone. + public var showLeftPanelButton: Bool + public var showRightPanelButton: Bool + public init() { hidden = false translucent = false diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift new file mode 100644 index 00000000..8f599be4 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PanelNavigationItemModelProtocol.swift @@ -0,0 +1,14 @@ +// +// PanelNavigationItemModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/18/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol PanelNavigationItemModelProtocol { + var showLeftPanelButton: Bool { get set } + var showRightPanelButton: Bool { get set } +} diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index d750c79a..7ee850bc 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -6,4 +6,73 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation +public typealias BarButtonAction = (BarButtonItem) -> () + +@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + private var buttonAction: BarButtonAction? + + //-------------------------------------------------- + // MARK: - Delegate + //-------------------------------------------------- + + open weak var buttonDelegate: ButtonDelegateProtocol? + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + /// Creates the item with the passed in action. + public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + button.buttonAction = action + return button + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + @objc func callActionBlock(_ sender: BarButtonItem) { + buttonAction?(self) + } + + open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + buttonDelegate = delegateObject?.buttonDelegate + buttonAction = { [weak self] sender in + guard let self = self else { return } + if let data = try? actionModel.encode(using: JSONEncoder()), + let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], + delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) + } + } + } + + open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + buttonDelegate = delegateObject?.buttonDelegate + buttonAction = { [weak self] sender in + guard let self = self, + delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) + } + } +} + diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index c44a8d47..25a25e80 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -158,18 +158,26 @@ import UIKit needsUpdateUI = true view.setNeedsLayout() } - - /// Processes any new data. Called after the page is loaded the first time and on response updates for this page, - open func handleNewData() { - // TODO: remove legacy. Temporary, convert legacy to navigation model. - var navigationModel = pageModel?.navigationItem ?? NavigationItemModel() + + /// Creates a legacy navigation model. + open func createDefaultLegacyNavigationModel() -> NavigationItemModel { + let navigationModel = NavigationItemModel() navigationModel.title = pageModel?.screenHeading navigationModel.showLeftPanelButton = isMasterInitiallyAccessible() navigationModel.showRightPanelButton = isSupportInitiallyAccessible() if /*(self as? MVMCoreUITabBarPageControlViewController) != nil ||*/ manager != nil || loadObject?.requestParameters?.tabWasPressed ?? false == true { navigationModel.line = LineModel(type: .none) } - pageModel?.navigationItem = navigationModel + return navigationModel + } + + /// Processes any new data. Called after the page is loaded the first time and on response updates for this page, + open func handleNewData() { + // TODO: remove legacy. Temporary, convert legacy to navigation model. + if pageModel?.navigationItem == nil { + pageModel?.navigationItem = createDefaultLegacyNavigationModel() + } + if formValidator == nil { let rules = pageModel?.formRules formValidator = FormValidator(rules) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 4150da12..5402cae1 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -63,10 +63,13 @@ import UIKit // Update icons if main navigation controller. if navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController { - // Update Panels - MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(navigationItemModel.showLeftPanelButton , for: viewController) - MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(navigationItemModel.showRightPanelButton , for: viewController) MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + + // Update Panels + if let model = navigationItemModel as? PanelNavigationItemModelProtocol { + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) + MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) + } } } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index f5c07d04..dfc2fda3 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -12,6 +12,7 @@ @import MVMCore.MVMCoreViewManagerProtocol; @import MVMCore.MVMCoreObject; @import MVMCore.MVMCoreActionUtility; +@import MVMCore.NSDictionary_MFConvenience; #import "MVMCoreUIUtility.h" #import "UIColor+MFConvenience.h" #import "NSLayoutConstraint+MFConvenience.h" @@ -106,17 +107,31 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { - return nil; +- (nullable NSArray *)createNavigationItemsFrom:(nonnull NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + if (JSONlist.count == 0) { return nil; } + NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; + for (NSDictionary *itemData in JSONlist) { + UIImage *image = [UIImage imageNamed:[itemData string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; + BarButtonItem *item = [BarButtonItem createWith:image actionMap:[itemData dict:@"action"] delegateObject:delegateObject additionalData:nil]; + [items addObject:item]; } + return items; +} + +- (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } UIViewController *controller = (UIViewController *)viewController; - controller.page - return nil; + NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { - return nil; + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } + UIViewController *controller = (UIViewController *)viewController; + NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (CGFloat)leftPanelExtendedWidth { @@ -244,7 +259,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } - NSArray *extraButtons = [self additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController]; + NSArray *extraButtons = [self additionalLeftButtonsForViewController:viewController]; if (extraButtons) { [leftBarButtonItems addObjectsFromArray:extraButtons]; } @@ -415,7 +430,7 @@ CGFloat const PanelAnimationDuration = 0.2; if ((accessible && !extended) && self.rightPanelButton) { [navigationItems addObject:self.rightPanelButton]; } - NSArray *extraButtons = [self additionalRightButtonsForViewController:(nonnull UIViewController *)viewController]; + NSArray *extraButtons = [self additionalRightButtonsForViewController:viewController]; if (extraButtons) { [navigationItems addObjectsFromArray:extraButtons]; } From fc8f189b77a7ae394c050f3af59f05fa195fe9ab Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 18 May 2020 21:54:21 -0400 Subject: [PATCH 10/33] fix funny defect --- MVMCoreUI/BaseControllers/ViewController.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 25a25e80..782deae2 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -175,7 +175,8 @@ import UIKit open func handleNewData() { // TODO: remove legacy. Temporary, convert legacy to navigation model. if pageModel?.navigationItem == nil { - pageModel?.navigationItem = createDefaultLegacyNavigationModel() + let navigationItem = createDefaultLegacyNavigationModel() + pageModel?.navigationItem = navigationItem } if formValidator == nil { From 76326a1a34ddb06df3c088bad9805aced781a623 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 19 May 2020 09:42:35 -0400 Subject: [PATCH 11/33] modal accessibility --- .../Items/MoleculeCollectionViewCell.swift | 8 ++-- .../Templates/ModalMoleculeListTemplate.swift | 12 +++++- .../Templates/MoleculeListTemplate.swift | 1 + .../BaseClasses/CollectionViewCell.swift | 37 ++++++++++++++----- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift index 10b51bff..2306dc94 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionViewCell.swift @@ -10,10 +10,11 @@ import UIKit /// A collection item that is a container for any molecule. open class MoleculeCollectionViewCell: CollectionViewCell { - + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let collectionModel = model as? MoleculeCollectionItemModel else { return } + if molecule == nil { if let moleculeView = MoleculeObjectMapping.shared()?.createMolecule(collectionModel.molecule, delegateObject: delegateObject, additionalData: additionalData) { addMolecule(moleculeView) @@ -21,16 +22,15 @@ open class MoleculeCollectionViewCell: CollectionViewCell { } else { molecule?.set(with: collectionModel.molecule, delegateObject, additionalData) } - + guard let molecule = molecule as? (UIView & MVMCoreUIViewConstrainingProtocol) else { return } containerHelper.set(with: collectionModel, for: molecule) - accessibilityElements = molecule.subviews } open override func reset() { super.reset() molecule?.reset() - backgroundColor = .white + backgroundColor = .mvmWhite } open class func nameForReuse(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift index a141ef0e..63140e6e 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift @@ -8,6 +8,7 @@ import UIKit + open class ModalMoleculeListTemplate: MoleculeListTemplate { //-------------------------------------------------- // MARK: - Properties @@ -15,13 +16,20 @@ open class ModalMoleculeListTemplate: MoleculeListTemplate { public var closeButton: Button? + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + override open func handleNewData() { super.handleNewData() + closeButton = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { _ in MVMCoreNavigationHandler.shared()?.removeCurrentViewController() }) - + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() accessibilityElements = [closeButton as Any, tableView as Any] - UIAccessibility.post(notification: .layoutChanged, argument: closeButton) } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 521a0d45..4be4e025 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -8,6 +8,7 @@ import UIKit + open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol { //-------------------------------------------------- // MARK: - Stored Properties diff --git a/MVMCoreUI/BaseClasses/CollectionViewCell.swift b/MVMCoreUI/BaseClasses/CollectionViewCell.swift index e11b350c..aa74d229 100644 --- a/MVMCoreUI/BaseClasses/CollectionViewCell.swift +++ b/MVMCoreUI/BaseClasses/CollectionViewCell.swift @@ -8,9 +8,13 @@ import Foundation + /// A base collection view cell with basic mvm functionality. open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCoreViewProtocol, CollectionTemplateItemProtocol { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // Convenience helpers open var molecule: MoleculeViewProtocol? public let containerHelper = ContainerHelper() @@ -18,9 +22,13 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo /// The width, used for establishing columns open var width: CGFloat? - + private var initialSetupPerformed = false - + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - Inits public override init(frame: CGRect) { super.init(frame: .zero) @@ -39,6 +47,10 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo } } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol open func setupView() { isAccessibilityElement = false @@ -58,15 +70,19 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo open func reset() { molecule?.reset() - backgroundColor = .white + backgroundColor = .mvmWhite width = nil } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? CollectionItemModelProtocol else { return } self.model = model - + if let moleculeModel = model as? MoleculeModelProtocol, let backgroundColor = moleculeModel.backgroundColor { self.backgroundColor = backgroundColor.uiColor @@ -84,8 +100,11 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo containerHelper.constrainView(molecule) self.molecule = molecule } - + + //-------------------------------------------------- // MARK: - CollectionTemplateItemProtocol + //-------------------------------------------------- + public func set(width: CGFloat) { self.width = width } @@ -94,11 +113,11 @@ open class CollectionViewCell: UICollectionViewCell, MoleculeViewProtocol, MVMCo override open func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes) guard let width = width else { return autoLayoutAttributes } - + let targetSize = CGSize(width: width, height: 0) - let newSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.defaultLow) + let newSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow) let newFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: newSize) autoLayoutAttributes.frame = newFrame return autoLayoutAttributes - } + } } From cbe1c043867987ba1e7d2ea90c04e26a9646c893 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 10:42:08 -0400 Subject: [PATCH 12/33] fix to action block MF call super --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 7ee850bc..9c09016b 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -27,21 +27,21 @@ public typealias BarButtonAction = (BarButtonItem) -> () /// Creates the item with the passed in action. public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock)) + let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) button.buttonAction = action return button } From bb506717114c48c242f352ba4d9ba18e587a2f87 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 12:48:56 -0400 Subject: [PATCH 13/33] target issue fix --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 38 +++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 9c09016b..51142a5a 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -8,41 +8,51 @@ public typealias BarButtonAction = (BarButtonItem) -> () -@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- +@objc fileprivate class ActionDelegate: NSObject { + fileprivate var buttonAction: BarButtonAction? + @objc fileprivate func callActionBlock(_ sender: BarButtonItem) { + buttonAction?(sender) + } +} - private var buttonAction: BarButtonAction? +@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol { //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - + private var actionObject: ActionDelegate? + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- + public static func create(with image: UIImage) -> Self { + let actionObject = ActionDelegate() + let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionObject = actionObject + return button + } + /// Creates the item with the passed in action. public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) + let button = create(with: image) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) + let button = create(with: image) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { - let button = self.init(image: image, style: .plain, target: self, action: #selector(callActionBlock(_:))) - button.buttonAction = action + let button = create(with: image) + button.actionObject?.buttonAction = action return button } @@ -50,13 +60,9 @@ public typealias BarButtonAction = (BarButtonItem) -> () // MARK: - Methods //-------------------------------------------------- - @objc func callActionBlock(_ sender: BarButtonItem) { - buttonAction?(self) - } - open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - buttonAction = { [weak self] sender in + actionObject?.buttonAction = { [weak self] sender in guard let self = self else { return } if let data = try? actionModel.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], @@ -68,7 +74,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - buttonAction = { [weak self] sender in + actionObject?.buttonAction = { [weak self] sender in guard let self = self, delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) From d203285c738a3f82fdf22429926f38128382650e Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 19:05:55 -0400 Subject: [PATCH 14/33] Cleanup navigation button creation. --- .../NavigationItemButtonModel.swift | 6 +++ MVMCoreUI/BaseClasses/BarButtonItem.swift | 8 +-- .../Containers/NavigationController.swift | 54 ++++++++++++++----- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift index 9110bfe9..7a81cb5b 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -32,4 +32,10 @@ public class NavigationItemButtonModel: Codable { try container.encode(imageName, forKey: .imageName) try container.encodeModel(action, forKey: .action) } + + /// Convenience function that creates a BarButtonItem for the model. + public func createNavigationItem(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) + return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + } } diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index 51142a5a..a2a2e9e6 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -28,7 +28,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () // MARK: - Initializers //-------------------------------------------------- - public static func create(with image: UIImage) -> Self { + public static func create(with image: UIImage?) -> Self { let actionObject = ActionDelegate() let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) button.actionObject = actionObject @@ -36,21 +36,21 @@ public typealias BarButtonAction = (BarButtonItem) -> () } /// Creates the item with the passed in action. - public static func create(with image: UIImage, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { let button = create(with: image) button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action map. - public static func create(with image: UIImage, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { let button = create(with: image) button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) return button } /// Creates the item with the passed in action. - public static func create(with image: UIImage, action: @escaping BarButtonAction) -> Self { + public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { let button = create(with: image) button.actionObject?.buttonAction = action return button diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 5402cae1..67506221 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -11,35 +11,60 @@ import UIKit @objcMembers open class NavigationController: UINavigationController { public var separatorView: Line? + /// Getter for the main navigation controller public static func navigationController() -> Self? { return MVMCoreActionUtility.initializerClassCheck(MVMCoreUISession.sharedGlobal()?.navigationController, classToVerify: self) as? Self } - public static func style(_ navigationBar: UINavigationBar) { + /// Provides MVM styling to the navigation bar. Returns a reference to the line. + public static func style(_ navigationBar: UINavigationBar) -> Line { UIColor.mfSetBackgroundColor(forNavigationBar: .white, navigationBar: navigationBar, transparent: false) 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() - style(navigationController.navigationBar) - navigationController.separatorView = Line(pinTo: navigationController.navigationBar, edge: .bottom, useMargin: false) - navigationController.separatorView?.setStyle(.standard) + navigationController.separatorView = style(navigationController.navigationBar) MVMCoreUISession.sharedGlobal()?.navigationController = navigationController MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn = navigationController MVMCoreNavigationHandler.shared()?.navigationController = 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 buttons. + public static func setNavigationButtons(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { + let delegate = (viewController as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject + var items: [UIBarButtonItem] = [] + if let backButtonModel = navigationItemModel.backButton, + navigationController.viewControllers.count > 1 { + items.append(backButtonModel.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + if let itemModels = navigationItemModel.additionalLeftButtons { + for item in itemModels { + items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + viewController.navigationItem.leftBarButtonItems = items + } + if let itemModels = navigationItemModel.additionalRightButtons { + for item in itemModels { + items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + } + viewController.navigationItem.rightBarButtonItems = items + } + } + /// Convenience function for setting navigation bar with model. public static func set(navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol, viewController: UIViewController) { viewController.navigationItem.title = navigationItemModel.title @@ -60,16 +85,21 @@ import UIKit navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none } + // Let legacy splitview controller handle buttons for now. + guard navigationController == MVMCoreUISplitViewController.main()?.splitViewController?.navigationController, + navigationController.topViewController == viewController else { + // Not the main split view controller, add buttons. + setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) + return + } + // Update icons if main navigation controller. - if navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController { - MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) - // Update Panels - if let model = navigationItemModel as? PanelNavigationItemModelProtocol { - MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) - MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) - } + // Update Panels + if let model = navigationItemModel as? PanelNavigationItemModelProtocol { + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(model.showLeftPanelButton, for: viewController) + MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(model.showRightPanelButton, for: viewController) } } } From 5a55312c9dea70fd3ceccac0924c3a59e9c70245 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 May 2020 19:57:02 -0400 Subject: [PATCH 15/33] typo fix --- MVMCoreUI/Containers/NavigationController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 67506221..170ce5b3 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -86,7 +86,7 @@ import UIKit } // Let legacy splitview controller handle buttons for now. - guard navigationController == MVMCoreUISplitViewController.main()?.splitViewController?.navigationController, + guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, navigationController.topViewController == viewController else { // Not the main split view controller, add buttons. setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) From 5bda356dc9cb8dcf48d3171c31ee141c186eeafd Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 11:00:02 -0400 Subject: [PATCH 16/33] Back button fix --- .../NavigationItemButtonModel.swift | 2 +- .../Containers/NavigationController.swift | 6 +-- .../MVMCoreUISplitViewController.m | 46 ++++++++++++++----- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift index 7a81cb5b..26be6952 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift @@ -34,7 +34,7 @@ public class NavigationItemButtonModel: Codable { } /// Convenience function that creates a BarButtonItem for the model. - public func createNavigationItem(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 170ce5b3..d62dec40 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -49,17 +49,17 @@ import UIKit var items: [UIBarButtonItem] = [] if let backButtonModel = navigationItemModel.backButton, navigationController.viewControllers.count > 1 { - items.append(backButtonModel.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } if let itemModels = navigationItemModel.additionalLeftButtons { for item in itemModels { - items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.leftBarButtonItems = items } if let itemModels = navigationItemModel.additionalRightButtons { for item in itemModels { - items.append(item.createNavigationItem(delegateObject: delegate, additionalData: nil)) + items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.rightBarButtonItems = items } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index dfc2fda3..d9814a1f 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -107,15 +107,13 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable NSArray *)createNavigationItemsFrom:(nonnull NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - if (JSONlist.count == 0) { return nil; } - NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; - for (NSDictionary *itemData in JSONlist) { - UIImage *image = [UIImage imageNamed:[itemData string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; - BarButtonItem *item = [BarButtonItem createWith:image actionMap:[itemData dict:@"action"] delegateObject:delegateObject additionalData:nil]; - [items addObject:item]; - } - return items; +- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController { + if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; } + UIViewController *controller = (UIViewController *)viewController; + NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]]; + if (!item) { return self.backButton; } + DelegateObject *delegate = [controller delegateObject]; + return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { @@ -123,7 +121,7 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = (UIViewController *)viewController; NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { @@ -131,7 +129,7 @@ CGFloat const PanelAnimationDuration = 0.2; UIViewController *controller = (UIViewController *)viewController; NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; } - (CGFloat)leftPanelExtendedWidth { @@ -254,7 +252,13 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; if ([viewController.navigationController.viewControllers count] > 1) { - [leftBarButtonItems addObject:self.backButton]; + UIBarButtonItem *button = [self getBackButtonForViewController:viewController]; + if (button) { + viewController.navigationItem.hidesBackButton = YES; + [leftBarButtonItems addObject:button]; + } else { + viewController.navigationItem.hidesBackButton = NO; + } } if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; @@ -621,6 +625,24 @@ CGFloat const PanelAnimationDuration = 0.2; #pragma mark - Other Panel Functions +/// Convenience function, creates a BarButtonItem from button json +- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; + BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil]; + return item; +} + +/// Convenience function, creates a list of BarButtonItems list of json +- (nullable NSArray *)createNavigationItemButtonsFrom:(nullable NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { + if (JSONlist.count == 0) { return nil; } + NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; + for (NSDictionary *itemData in JSONlist) { + UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject]; + [items addObject:item]; + } + return items; +} + - (void)forceHideBothDrawers { [self hideBothDrawersShouldForceHide:YES]; } From 5e7745655755b7756e3c0a10326b9a630089f6cb Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 20 May 2020 16:05:09 -0400 Subject: [PATCH 17/33] removing unneeded caret statement --- MVMCoreUI/BaseClasses/TableViewCell.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index f07b1ee2..254a09f0 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -206,7 +206,6 @@ import UIKit caret.translatesAutoresizingMaskIntoConstraints = true caret.isAccessibilityElement = true caret.accessibilityTraits = .button - caret.accessibilityLabel = "Caret," caret.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "AccTabHint") caret.size = .small(.vertical) if let size = caret.size?.dimensions() { From d40f41e7bb9671fcdbeb5596634a2f105539e286 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 19:38:37 -0400 Subject: [PATCH 18/33] cleaning --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++++ .../Atomic/Molecules/Items/CarouselItem.swift | 2 +- MVMCoreUI/Atomic/Organisms/Carousel.swift | 18 ++++++++---------- MVMCoreUI/Atomic/Organisms/CarouselModel.swift | 8 ++++---- .../CarouselItemModelProtocol.swift | 4 +--- .../ModelProtocols/CarouselItemProtocol.swift | 15 +++++++++++++++ 6 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d7afb970..7b35fc55 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -266,6 +266,7 @@ D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */; }; D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; @@ -680,6 +681,7 @@ D236E5B2241FEB1000C38625 /* ListTwoColumnPriceDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescription.swift; sourceTree = ""; }; D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; @@ -850,6 +852,7 @@ children = ( D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */, 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */, + D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */, 012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */, 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */, 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */, @@ -2226,6 +2229,7 @@ 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, 525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, + D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */, D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift index 3089596a..a37fe016 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/CarouselItem.swift @@ -8,7 +8,7 @@ import Foundation -open class CarouselItem: MoleculeCollectionViewCell { +open class CarouselItem: MoleculeCollectionViewCell, CarouselItemProtocol { open var allowsPeaking = false var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate)) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel.swift index 30d4c21e..9fa72b5d 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel.swift @@ -36,7 +36,7 @@ open class Carousel: View { open var numberOfPages = 0 /// The models for the molecules. - var molecules: [MoleculeModelProtocol]? + var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]? /// The horizontal alignment of the cell in the collection view. Only noticeable if the itemWidthPercent is less than 100%. public var itemAlignment = UICollectionView.ScrollPosition.left @@ -176,11 +176,9 @@ open class Carousel: View { if carouselModel?.loop ?? false && newMolecules.count > 1 { // Sets up the row data with buffer cells on each side (for illusion of endless scroll... also has one more buffer cell on each side in case we can peek that cell). loop = true - - molecules?.insert(newMolecules.last!, at: 0) - molecules?.insert(newMolecules[(newMolecules.count - 2)], at: 0) - molecules?.append(newMolecules.first!) - molecules?.append(newMolecules[1]) + + molecules?.insert(contentsOf: newMolecules.suffix(2), at: 0) + molecules?.append(contentsOf: newMolecules.prefix(2)) } pageIndex = 0 @@ -259,15 +257,15 @@ open class Carousel: View { let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row } if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex { - (collectionView.cellForItem(at: firstItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: firstItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } if let lastItem = visibleItemsPaths.last, lastItem.row != currentIndex { - (collectionView.cellForItem(at: lastItem) as? CarouselItem)?.setPeaking(true, animated: true) + (collectionView.cellForItem(at: lastItem) as? CarouselItemProtocol)?.setPeaking(true, animated: true) } } else { // Hide peaking. for item in collectionView.visibleCells { - (item as? CarouselItem)?.setPeaking(false, animated: true) + (item as? CarouselItemProtocol)?.setPeaking(false, animated: true) } } } @@ -301,7 +299,7 @@ extension Carousel: UICollectionViewDelegateFlowLayout { } open func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { - (cell as? CarouselItem)?.setPeaking(false, animated: false) + (cell as? CarouselItemProtocol)?.setPeaking(false, animated: false) } } diff --git a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift index 857901e8..5ff753aa 100644 --- a/MVMCoreUI/Atomic/Organisms/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/CarouselModel.swift @@ -19,7 +19,7 @@ import UIKit } public var backgroundColor: Color? - public var molecules: [CarouselItemModel] + public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] public var index: Int = 0 public var spacing: Float? public var border: Bool? @@ -29,7 +29,7 @@ import UIKit public var itemAlignment: UICollectionView.ScrollPosition? public var pagingMolecule: (CarouselPagingModelProtocol & MoleculeModelProtocol)? - public init(molecules: [CarouselItemModel]) { + public init(molecules: [MoleculeModelProtocol & CarouselItemModelProtocol]) { self.molecules = molecules } @@ -57,7 +57,7 @@ import UIKit required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decode([CarouselItemModel].self, forKey: .molecules) + molecules = try typeContainer.decodeModels(codingKey: .molecules) index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0 backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) spacing = try typeContainer.decodeIfPresent(Float.self, forKey: .spacing) @@ -73,7 +73,7 @@ import UIKit var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encode(molecules, forKey: .molecules) + try container.encodeModels(molecules, forKey: .molecules) try container.encode(spacing, forKey: .spacing) try container.encode(border, forKey: .border) try container.encode(loop, forKey: .loop) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift index 093c9337..198cf80d 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift @@ -9,7 +9,5 @@ import Foundation -public protocol CarouselItemModelProtocol: ContainerModelProtocol, MoleculeModelProtocol { - var peakingUI: Bool? { get } - var peakingArrowColor: Color? { get } +public protocol CarouselItemModelProtocol: ContainerModelProtocol { } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift new file mode 100644 index 00000000..4f49e5f7 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemProtocol.swift @@ -0,0 +1,15 @@ +// +// CarouselItemProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/20/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol CarouselItemProtocol: UICollectionViewCell { + + /// Notifies the cell if it is peaking or not. + func setPeaking(_ peaking: Bool, animated: Bool) +} From 79127889dd7e8fecaefbee688069cc54e8166d2d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 20:28:13 -0400 Subject: [PATCH 19/33] name change --- MVMCoreUI/BaseClasses/BarButtonItem.swift | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index a2a2e9e6..ac26c040 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -22,7 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - private var actionObject: ActionDelegate? + private var actionDelegate: ActionDelegate? //-------------------------------------------------- // MARK: - Initializers @@ -31,7 +31,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () public static func create(with image: UIImage?) -> Self { let actionObject = ActionDelegate() let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) - button.actionObject = actionObject + button.actionDelegate = actionObject return button } @@ -52,7 +52,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () /// Creates the item with the passed in action. public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { let button = create(with: image) - button.actionObject?.buttonAction = action + button.actionDelegate?.buttonAction = action return button } @@ -62,11 +62,10 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - actionObject?.buttonAction = { [weak self] sender in - guard let self = self else { return } + actionDelegate?.buttonAction = { sender in if let data = try? actionModel.encode(using: JSONEncoder()), let actionMap = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.init()) as? [AnyHashable: Any], - delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } @@ -74,9 +73,8 @@ public typealias BarButtonAction = (BarButtonItem) -> () open func set(with actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { buttonDelegate = delegateObject?.buttonDelegate - actionObject?.buttonAction = { [weak self] sender in - guard let self = self, - delegateObject?.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } + actionDelegate?.buttonAction = { sender in + guard delegateObject?.buttonDelegate?.button?(sender, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true else { return } MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } From 518672f4f37433061ea3ccbde7fbcb414842b6ec Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 20 May 2020 20:40:22 -0400 Subject: [PATCH 20/33] addressing review comments --- MVMCoreUI/Containers/NavigationController.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index d62dec40..3f7846a0 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -51,14 +51,14 @@ import UIKit navigationController.viewControllers.count > 1 { items.append(backButtonModel.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } - if let itemModels = navigationItemModel.additionalLeftButtons { - for item in itemModels { + if let leftItemModels = navigationItemModel.additionalLeftButtons { + for item in leftItemModels { items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.leftBarButtonItems = items } - if let itemModels = navigationItemModel.additionalRightButtons { - for item in itemModels { + if let rightItemModels = navigationItemModel.additionalRightButtons { + for item in rightItemModels { items.append(item.createNavigationItemButton(delegateObject: delegate, additionalData: nil)) } viewController.navigationItem.rightBarButtonItems = items From 7bf03d941845d26e6c89ad6a792bd145bf344f67 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Thu, 21 May 2020 14:38:56 -0400 Subject: [PATCH 21/33] add button border and text color change to actionhandler setter. --- MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index eeff9cfe..a882035e 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -248,6 +248,8 @@ // Sets the color if (color) { + self.button.layer.borderColor = color.CGColor; + [self.button setTitleColor:color forState:UIControlStateNormal]; [self.closeButton setTintColor:color]; } From 5f1fa847db4f70f91915863cdf1cbe164de24dfc Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Thu, 21 May 2020 15:09:04 -0400 Subject: [PATCH 22/33] squash feature/list_leftvariable_numberedlist_alltextlinks --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + ...tVariableNumberedListAllTextAndLinks.swift | 60 +++++++++++++++++++ ...ableNumberedListAllTextAndLinksModel.swift | 42 +++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift create mode 100644 MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b8fbede1..292e4157 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -114,6 +114,8 @@ 27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */; }; 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */; }; 31BE15CC23D8924D00452370 /* CheckboxModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31BE15CA23D8924C00452370 /* CheckboxModel.swift */; }; + 32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */; }; + 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */; }; 522679C123FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */; }; 522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */; }; 52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */; }; @@ -537,6 +539,8 @@ 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBrightnessModifierBehavior.swift; sourceTree = ""; }; 31BE15C923D8924C00452370 /* CheckboxLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxLabelModel.swift; sourceTree = ""; }; 31BE15CA23D8924C00452370 /* CheckboxModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckboxModel.swift; sourceTree = ""; }; + 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinksModel.swift; sourceTree = ""; }; + 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableNumberedListAllTextAndLinks.swift; sourceTree = ""; }; 522679BF23FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinks.swift; sourceTree = ""; }; 522679C023FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableCheckboxAllTextAndLinksModel.swift; sourceTree = ""; }; 52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinks.swift; sourceTree = ""; }; @@ -1299,6 +1303,8 @@ 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */, AA99724F2475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift */, AA997251247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift */, + 32F8804524765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift */, + 32F8804724765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift */, ); path = LeftVariable; sourceTree = ""; @@ -1971,6 +1977,7 @@ 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, + 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, @@ -2180,6 +2187,7 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, + 32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */, 011D958524042432000E3791 /* RulesProtocol.swift in Sources */, AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */, AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index e46cfed0..18b3fee7 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -147,6 +147,7 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableRadioButtonBodyText.self, viewModelClass: ListLeftVariableRadioButtonBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableCheckboxBodyText.self, viewModelClass: ListLeftVariableCheckboxBodyTextModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableIconAllTextLinks.self, viewModelClass: ListLeftVariableIconAllTextLinksModel.self) + MoleculeObjectMapping.shared()?.register(viewClass: ListLeftVariableNumberedListAllTextAndLinks.self, viewModelClass: ListLeftVariableNumberedListAllTextAndLinksModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariablePayments.self, viewModelClass: ListRightVariablePaymentsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListRightVariableTotalData.self, viewModelClass: ListRightVariableTotalDataModel.self) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift new file mode 100644 index 00000000..e7a35cc6 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -0,0 +1,60 @@ +// +// ListLeftVariableNumberedListAllTextAndLinks.swift +// MVMCoreUI +// +// Created by Subhankar Acharya on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ListLeftVariableNumberedListAllTextAndLinks: TableViewCell { + //----------------------------------------------------- + // MARK: - Outlets + //----------------------------------------------------- + public let leftLabel = Label.createLabelTitle2XLarge(true) + public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero) + public var stack: Stack + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)), + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + axis: .horizontal) + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + //-------------------------------------------------- + // MARK: - Life Cycle + //-------------------------------------------------- + override open func setupView() { + super.setupView() + addMolecule(stack) + stack.restack() + } + + //------------------------------------------------------ + // MARK: - Molecule + //------------------------------------------------------ + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + super.set(with: model, delegateObject, additionalData) + guard let model = model as? ListLeftVariableNumberedListAllTextAndLinksModel else { return } + leftLabel.text = String(model.number) + eyebrowHeadlineBodyLink.set(with: model.eyebrowHeadlineBodyLink, delegateObject, additionalData) + } + + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + return 140 + } + + open override func reset() { + super.reset() + leftLabel.styleTitle2XLarge(true) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift new file mode 100644 index 00000000..78a85a8e --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinksModel.swift @@ -0,0 +1,42 @@ +// +// ListLeftVariableNumberedListAllTextAndLinksModel.swift +// MVMCoreUI +// +// Created by Subhankar Acharya on 21/05/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class ListLeftVariableNumberedListAllTextAndLinksModel: ListItemModel, MoleculeModelProtocol { + public static var identifier: String = "listLVNAll" + public var number: Int + public var eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel + + public init(number: Int, eyebrowHeadlineBodyLink: EyebrowHeadlineBodyLinkModel) { + self.number = number + self.eyebrowHeadlineBodyLink = eyebrowHeadlineBodyLink + super.init() + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case number + case eyebrowHeadlineBodyLink + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + number = try typeContainer.decode(Int.self, forKey: .number) + eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink) + try super.init(from: decoder) + } + + public override func encode(to encoder: Encoder) throws { + try super.encode(to: encoder) + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(number, forKey: .number) + try container.encode(eyebrowHeadlineBodyLink, forKey: .eyebrowHeadlineBodyLink) + } +} From 648da2bd3f7e43e6e1fa0a63378455a5d277366a Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Thu, 21 May 2020 15:29:24 -0400 Subject: [PATCH 23/33] Bug fix in label --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 087e893c..598f3f4e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -677,6 +677,9 @@ public typealias ActionBlock = () -> () @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber + // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. + preferredMaxLayoutWidth = size + if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) From 3f0828fa44e064785dd4ad6b89b165529c5bec7c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 21 May 2020 16:46:01 -0400 Subject: [PATCH 24/33] disabled and init --- .../Atomic/Atoms/Buttons/CaretLink.swift | 7 ++----- .../Atomic/Atoms/Buttons/CaretLinkModel.swift | 19 +++++++++++++------ MVMCoreUI/Atomic/Atoms/Views/Line.swift | 8 +------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift index 0e2dfd7b..b0822480 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLink.swift @@ -143,11 +143,8 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol { backgroundColor = color.uiColor } - enabledColor = (model.inverted ? model.enabled_inverted : model.enabledColor).uiColor - - if let color = model.disabledColor { - disabledColor = color.uiColor - } + enabledColor = (model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor + disabledColor = (model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor isEnabled = model.enabled set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 5b48deea..5a4a4c14 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -20,8 +20,9 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { public var title: String public var action: ActionModelProtocol public var enabledColor: Color = Color(uiColor: .mvmBlack) - public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6) - public var enabled_inverted: Color = Color(uiColor: .mvmWhite) + public var disabledColor: Color = Color(uiColor: .mvmCoolGray6) + public var enabledColor_inverted: Color = Color(uiColor: .mvmWhite) + public var disabledColor_inverted: Color = Color(uiColor: .mvmCoolGray10) public var enabled = true public var inverted = false @@ -42,7 +43,8 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { case backgroundColor case title case action - case enabled_inverted + case enabledColor_inverted + case disabledColor_inverted case enabledColor case disabledColor case enabled @@ -60,8 +62,12 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) - if let enabled_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabled_inverted) { - self.enabled_inverted = enabled_inverted + if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) { + self.enabledColor_inverted = enabledColor_inverted + } + + if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) { + self.disabledColor_inverted = disabledColor_inverted } if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor) { @@ -92,7 +98,8 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encode(enabled, forKey: .enabledColor) try container.encodeIfPresent(disabledColor, forKey: .disabledColor) try container.encode(enabled, forKey: .enabled) - try container.encode(enabled_inverted, forKey: .enabled_inverted) + try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted) + try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted) try container.encode(inverted, forKey: .inverted) } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Line.swift b/MVMCoreUI/Atomic/Atoms/Views/Line.swift index 7e05e2fa..22d33b1f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Line.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Line.swift @@ -47,9 +47,7 @@ import UIKit public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { self.init(frame: .zero) - - view.addSubview(self) - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: self, useMargins: useMargin, pinTop: edge != .bottom, pinBottom: edge != .top, pinLeft: edge != .right, pinRight: edge != .left).values)) + addLine(to: view, edge: edge, useMargin: useMargin) } //-------------------------------------------------- @@ -84,10 +82,6 @@ import UIKit //-------------------------------------------------- // MARK: - MoleculeViewProtocol //-------------------------------------------------- - public convenience init(pinTo view: UIView, edge: UIRectEdge, useMargin: Bool) { - self.init(frame: .zero) - addLine(to: view, edge: edge, useMargin: useMargin) - } open func addLine(to view: UIView, edge: UIRectEdge, useMargin: Bool) { view.addSubview(self) From 740545e9c30fcbc8eada62fba137727eb1d0e126 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 15:30:02 -0400 Subject: [PATCH 25/33] Try again --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 15 +++++++-------- ...tLeftVariableNumberedListAllTextAndLinks.swift | 3 ++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 598f3f4e..35d45ac6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -674,12 +674,15 @@ public typealias ActionBlock = () -> () setScale(scale) } + open override func layoutSubviews() { + super.layoutSubviews() + + // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. + preferredMaxLayoutWidth = frame.width + } + @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber - - // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. - preferredMaxLayoutWidth = size - if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) @@ -878,10 +881,6 @@ extension Label { return true } - public func horizontalAlignment() -> UIStackView.Alignment { - return .leading - } - public func copyBackgroundColor() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index e7a35cc6..9f2d62c9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -21,7 +21,7 @@ import Foundation //-------------------------------------------------- public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { stack = Stack.createStack(with: [(view: leftLabel, model: StackItemModel(horizontalAlignment: .fill)), - (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .leading))], + (view: eyebrowHeadlineBodyLink, model: StackItemModel(horizontalAlignment: .fill))], axis: .horizontal) super.init(style: style, reuseIdentifier: reuseIdentifier) } @@ -35,6 +35,7 @@ import Foundation //-------------------------------------------------- override open func setupView() { super.setupView() + leftLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal) addMolecule(stack) stack.restack() } From 528ae8a6854e1f137d804f6017a1e4f39bc32ecb Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 16:25:12 -0400 Subject: [PATCH 26/33] Fix for specific molecule --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 12 +++++------- ...ListLeftVariableNumberedListAllTextAndLinks.swift | 5 +++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 35d45ac6..087e893c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -674,15 +674,9 @@ public typealias ActionBlock = () -> () setScale(scale) } - open override func layoutSubviews() { - super.layoutSubviews() - - // This fixes a defect for when there are multiple labels stacked in a list item. Sometime some labels will not fill their available space. - preferredMaxLayoutWidth = frame.width - } - @objc public func updateView(_ size: CGFloat) { scaleSize = size as NSNumber + if let originalAttributedString = originalAttributedString { let attributedString = NSMutableAttributedString(attributedString: originalAttributedString) attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) @@ -881,6 +875,10 @@ extension Label { return true } + public func horizontalAlignment() -> UIStackView.Alignment { + return .leading + } + public func copyBackgroundColor() -> Bool { return true } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index 9f2d62c9..f00e7ff1 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -58,4 +58,9 @@ import Foundation super.reset() leftLabel.styleTitle2XLarge(true) } + + open override func layoutSubviews() { + super.layoutSubviews() + eyebrowHeadlineBodyLink.body.preferredMaxLayoutWidth = eyebrowHeadlineBodyLink.frame.width + } } From 1588644577ab84502f869dc16fe25c0aa090403f Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 16:28:05 -0400 Subject: [PATCH 27/33] comment --- .../ListLeftVariableNumberedListAllTextAndLinks.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift index f00e7ff1..d623311b 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableNumberedListAllTextAndLinks.swift @@ -61,6 +61,7 @@ import Foundation open override func layoutSubviews() { super.layoutSubviews() + // This fixes a defect body text where it doesn't layout correctly. eyebrowHeadlineBodyLink.body.preferredMaxLayoutWidth = eyebrowHeadlineBodyLink.frame.width } } From eb195afe1d0a51ab38484caf5bdea9eae0ff11a8 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 22 May 2020 16:30:14 -0400 Subject: [PATCH 28/33] fix for 3.0 --- MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift | 6 +++--- MVMCoreUI/Styles/Styler.swift | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 087e893c..d47a374f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -402,11 +402,11 @@ public typealias ActionBlock = () -> () attributedString.insert(mutableString, at: imageAtt.location) case let fontAtt as LabelAttributeFontModel: - if let fontStyle = fontAtt.style?.rawValue { - let styles = MFStyler.styleGetAttributedString("0", withStyle: fontStyle) + if let fontStyle = fontAtt.style { attributedString.removeAttribute(.font, range: range) attributedString.removeAttribute(.foregroundColor, range: range) - attributedString.addAttributes(styles.attributes(at: 0, effectiveRange: nil), range: range) + attributedString.addAttribute(.font, value: fontStyle.getFont(), range: range) + attributedString.addAttribute(.foregroundColor, value: fontStyle.color(), range: range) } else { let fontSize = fontAtt.size var font: UIFont? diff --git a/MVMCoreUI/Styles/Styler.swift b/MVMCoreUI/Styles/Styler.swift index d8d0a519..43e4d319 100644 --- a/MVMCoreUI/Styles/Styler.swift +++ b/MVMCoreUI/Styles/Styler.swift @@ -81,6 +81,16 @@ open class Styler { } } + public func color() -> UIColor { + switch self { + case .B3: + return .mvmCoolGray6 + + default: + return .mvmBlack + } + } + /// Determines if the selected font case is bold or regular. public func isBold() -> Bool { From 428baa0012883f81736f2c410cda8b00704adc43 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:31:32 -0400 Subject: [PATCH 29/33] remove transparency, unused --- .../NavigationBar/NavigationItemModel.swift | 5 ---- .../NavigationItemModelProtocol.swift | 1 - MVMCoreUI/Categories/UIColor+Extension.swift | 25 ------------------- MVMCoreUI/Categories/UIColor+MFConvenience.h | 3 --- MVMCoreUI/Categories/UIColor+MFConvenience.m | 21 ---------------- .../Containers/NavigationController.swift | 4 +-- 6 files changed, 2 insertions(+), 57 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 38dee0d2..41a35182 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -16,7 +16,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public var title: String? public var hidden: Bool public var backgroundColor: Color? - public var translucent: Bool public var tintColor: Color public var line: LineModel? public var backButton: NavigationItemButtonModel? @@ -29,7 +28,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt public init() { hidden = false - translucent = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) @@ -42,7 +40,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt case title case hidden case backgroundColor - case translucent case tintColor case line case backButton @@ -57,7 +54,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt 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: .white) - translucent = try typeContainer.decodeIfPresent(Bool.self, forKey: .translucent) ?? false tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) @@ -72,7 +68,6 @@ public class NavigationItemModel: NavigationItemModelProtocol, PanelNavigationIt try container.encodeIfPresent(title, forKey: .title) try container.encode(hidden, forKey: .hidden) try container.encode(backgroundColor, forKey: .backgroundColor) - try container.encode(translucent, forKey: .translucent) try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) try container.encodeIfPresent(backButton, forKey: .backButton) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 634539d4..0bd192e3 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -12,7 +12,6 @@ public protocol NavigationItemModelProtocol { var title: String? { get set } var hidden: Bool { get set } var backgroundColor: Color? { get set } - var translucent: Bool { get set } var tintColor: Color { get set } var line: LineModel? { get set } var backButton: NavigationItemButtonModel? { get set } diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 1ef2e217..78be926d 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -269,31 +269,6 @@ extension UIColor { return .white } - public class func setBackgroundColor(_ color: UIColor, for navigationBar: UINavigationBar, isTransparent: Bool) { - - DispatchQueue.main.async { - - let view = UIView(frame: CGRect(x: 0, y: 0, width: 1, height: 1)) - view.backgroundColor = color - - UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0) - - if let context = UIGraphicsGetCurrentContext() { - view.layer.render(in: context) - } - - let image = UIGraphicsGetImageFromCurrentImageContext() - UIGraphicsEndImageContext() - - if isTransparent { - navigationBar.setBackgroundImage(UIImage(), for: .default) - navigationBar.isTranslucent = false - } else { - navigationBar.setBackgroundImage(image, for: .default) - } - } - } - /// - parameter color: The UIColor intended to retrieve its hex value. public class func hexString(for color: UIColor) -> String? { diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.h b/MVMCoreUI/Categories/UIColor+MFConvenience.h index 92b28a36..97280ba1 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.h +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.h @@ -183,9 +183,6 @@ // Returns a gradient lighter color; + (nonnull UIColor *)mfGradientColor:(nullable UIColor *)color; -// Sets the background color for the nav bar. -+ (void)mfSetBackgroundColorForNavigationBar:(nonnull UIColor *)color navigationBar:(nonnull UINavigationBar *)navigationBar transparent:(BOOL)transparent; - #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color; diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index 33df3848..8786df01 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -389,27 +389,6 @@ return [UIColor whiteColor]; } - -+ (void)mfSetBackgroundColorForNavigationBar:(nonnull UIColor *)color navigationBar:(nonnull UINavigationBar *)navigationBar transparent:(BOOL)transparent { - - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)]; - view.backgroundColor = color; - UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); - [view.layer renderInContext:UIGraphicsGetCurrentContext()]; - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - if (transparent) { - [navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - [navigationBar setTranslucent:NO]; - - } else { - [navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault]; - - } - }]; -} - #pragma mark - Hex String + (nullable NSString *)hexStringForColor:(nonnull UIColor*)color { diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 3f7846a0..4367f2e1 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -18,7 +18,7 @@ import UIKit /// Provides MVM styling to the navigation bar. Returns a reference to the line. public static func style(_ navigationBar: UINavigationBar) -> Line { - UIColor.mfSetBackgroundColor(forNavigationBar: .white, navigationBar: navigationBar, transparent: false) + navigationBar.backgroundColor = .white navigationBar.shadowImage = UIImage() navigationBar.isOpaque = true navigationBar.tintColor = .black @@ -72,7 +72,7 @@ import UIKit viewController.navigationItem.hidesBackButton = (navigationItemModel.backButton != nil) navigationController.setNavigationBarHidden(navigationItemModel.hidden, animated: true) - UIColor.setBackgroundColor(navigationItemModel.backgroundColor?.uiColor ?? .white, for: navigationController.navigationBar, isTransparent: navigationItemModel.translucent) + navigationController.navigationBar.barTintColor = navigationItemModel.backgroundColor?.uiColor ?? .white let tint = navigationItemModel.tintColor.uiColor navigationController.navigationBar.tintColor = tint From 4b9ea6a799d3bdcb42966cee3175457d980334c2 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:36:21 -0400 Subject: [PATCH 30/33] adds background color to tabs --- .../Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index dc8b9cae..72773031 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -153,10 +153,11 @@ import UIKit override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) + backgroundColor = tabsModel?.backgroundColor?.uiColor self.delegateObject = delegateObject self.additionalData = additionalData - self.selectedIndex = tabsModel?.selectedIndex ?? 0 - self.bottomLine.backgroundColor = tabsModel?.selectedColor.uiColor + selectedIndex = tabsModel?.selectedIndex ?? 0 + bottomLine.backgroundColor = tabsModel?.selectedColor.uiColor reloadData() } } From 0efd49e6f4e68d1b0c32510ae0c5e96897339d27 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:37:10 -0400 Subject: [PATCH 31/33] color add --- .../Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 72773031..60b31225 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -237,13 +237,13 @@ extension Tabs: UICollectionViewDelegateFlowLayout { collect.selectItem(at: indexPath, animated: animated, scrollPosition: .centeredHorizontally) guard let tabCell = collect.cellForItem(at: indexPath) as? TabItemCell, let tabsModel = self.tabsModel else { return } - self.moveBottomLine(toIndex: indexPath, animated: animated, cell: tabCell) + moveBottomLine(toIndex: indexPath, animated: animated, cell: tabCell) tabCell.label.textColor = tabsModel.selectedColor.uiColor tabCell.updateAccessibility(indexPath: indexPath, selected: true, tabsModel: tabsModel) tabCell.setNeedsDisplay() tabCell.setNeedsLayout() tabCell.layoutIfNeeded() - self.delegate?.didSelectItem(indexPath, tabs: self) + delegate?.didSelectItem(indexPath, tabs: self) } } From ba0a748ad3d344ddbbd1dfcbf93844ba3177b962 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 22 May 2020 18:38:57 -0400 Subject: [PATCH 32/33] remove duplicate --- MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift index 60b31225..8a6cb82d 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/Tabs.swift @@ -153,7 +153,6 @@ import UIKit override open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { super.set(with: model, delegateObject, additionalData) - backgroundColor = tabsModel?.backgroundColor?.uiColor self.delegateObject = delegateObject self.additionalData = additionalData selectedIndex = tabsModel?.selectedIndex ?? 0 From e020a395745c9662f22dae7b11ca3b609f501f90 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 27 May 2020 09:56:22 -0400 Subject: [PATCH 33/33] corrections made --- MVMCoreUI/Atomic/Atoms/Views/Arrow.swift | 9 +++------ .../Views/CarouselIndicator/CarouselIndicator.swift | 9 +++------ MVMCoreUI/Atomic/Atoms/Views/LineModel.swift | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift index 0a3e0457..a437f9d8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Arrow.swift @@ -42,15 +42,12 @@ open class Arrow: View { open var color: UIColor { get { - if let model = arrowModel, model.inverted { - return arrowModel?.color_inverted.uiColor ?? .mvmWhite - } else { - return arrowModel?.color.uiColor ?? .mvmBlack - } + guard let model = arrowModel else { return .mvmBlack } + return model.inverted ? model.color_inverted.uiColor : model.color.uiColor } set { if let model = arrowModel, model.inverted { - arrowModel?.color_inverted = Color(uiColor: newValue) + model.color_inverted = Color(uiColor: newValue) } else { arrowModel?.color = Color(uiColor: newValue) } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift index e202a212..6bff6e6b 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicator.swift @@ -79,15 +79,12 @@ open class CarouselIndicator: Control, CarouselPageControlProtocol { public var indicatorColor: UIColor { get { - if let model = carouselIndicatorModel, model.inverted { - return carouselIndicatorModel?.indicatorColor_inverted.uiColor ?? .mvmWhite - } else { - return carouselIndicatorModel?.indicatorColor.uiColor ?? .mvmBlack - } + guard let model = carouselIndicatorModel else { return .mvmBlack } + return model.inverted ? model.indicatorColor_inverted.uiColor : model.indicatorColor.uiColor } set { if let model = carouselIndicatorModel, model.inverted { - carouselIndicatorModel?.indicatorColor_inverted = Color(uiColor: newValue) + model.indicatorColor_inverted = Color(uiColor: newValue) } else { carouselIndicatorModel?.indicatorColor = Color(uiColor: newValue) } diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index 8a245066..3189deab 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -106,7 +106,6 @@ import UIKit } if let backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted) { - self.backgroundColor_inverted = backgroundColor_inverted } @@ -121,6 +120,7 @@ import UIKit try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(backgroundColor_inverted, forKey: .backgroundColor_inverted) try container.encodeIfPresent(useVerticalLine, forKey: .useVerticalLine) } }