latest updated for color inversion

This commit is contained in:
Kevin G Christiano 2020-04-30 14:26:25 -04:00
parent a9af2f98ac
commit 80b9f985b1
10 changed files with 414 additions and 107 deletions

View File

@ -102,6 +102,7 @@
0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */; }; 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86223D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift */; };
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; };
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; };
0A96140B245B06F0006FA18B /* Facade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A96140A245B06F0006FA18B /* Facade.swift */; };
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; }; 0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; }; 0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; };
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; }; 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; };
@ -558,6 +559,7 @@
0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = "<group>"; }; 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = "<group>"; }; 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = "<group>"; };
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
0A96140A245B06F0006FA18B /* Facade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Facade.swift; sourceTree = "<group>"; };
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; }; 0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; }; 0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = "<group>"; }; 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = "<group>"; };
@ -1715,6 +1717,7 @@
D29DF13921E68637003B2FB9 /* MFStyler.m */, D29DF13921E68637003B2FB9 /* MFStyler.m */,
0A6682A92435125F00AD3CA1 /* Styler.swift */, 0A6682A92435125F00AD3CA1 /* Styler.swift */,
0A6682AB243531C300AD3CA1 /* Padding.swift */, 0A6682AB243531C300AD3CA1 /* Padding.swift */,
0A96140A245B06F0006FA18B /* Facade.swift */,
); );
path = Styles; path = Styles;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2239,6 +2242,7 @@
012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */, 012A88C4238D86E600FE3DA1 /* CarouselItemModelProtocol.swift in Sources */,
D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */, D2E2A9A123E095AB000B42E6 /* ButtonModelProtocol.swift in Sources */,
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */, 94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */,
0A96140B245B06F0006FA18B /* Facade.swift in Sources */,
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */, D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */,
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */, 52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */,
525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */, 525239C02407BCFF00454969 /* ListTwoColumnPriceDetailsModel.swift in Sources */,

View File

@ -26,20 +26,52 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
public static var identifier: String = "button" public static var identifier: String = "button"
public var backgroundColor: Color? public var backgroundColor: Color?
public var isInverted: Bool = false
public var title: String public var title: String
public var action: ActionModelProtocol public var action: ActionModelProtocol
public var enabled: Bool = true public var enabled: Bool = true
public var style: ButtonStyle? public var isInverted: Bool = false {
didSet { facade?.isInverted = isInverted }
}
public var facade: Facade?
public var style: ButtonStyle = .primary {
didSet {
switch style {
case .primary:
facade = primaryFacade
case .secondary:
facade = secondaryFacade
}
}
}
public var size: ButtonSize? = .standard public var size: ButtonSize? = .standard
public var fillColor: Color?
public var textColor: Color?
public var borderColor: Color?
public var disabledFillColor: Color?
public var disabledTextColor: Color?
public var disabledBorderColor: Color?
public var groupName: String = "" public var groupName: String = ""
//--------------------------------------------------
// MARK: - Default Button Facades
//--------------------------------------------------
private var primaryFacade = Facade(enabledFillColor: Color(uiColor: .mvmBlack),
enabledTextColor: Color(uiColor: .mvmWhite),
disabledFillColor: Color(uiColor: .mvmCoolGray6),
disabledTextColor: Color(uiColor: .mvmWhite),
enabledFillColor_inverted: Color(uiColor: .mvmWhite),
enabledTextColor_inverted: Color(uiColor: .mvmBlack),
disabledFillColor_inverted: Color(uiColor: .mvmCoolGray6),
disabledTextColor_inverted: Color(uiColor: .mvmBlack))
private var secondaryFacade = Facade(enabledFillColor: Color(uiColor: .mvmWhite),
enabledTextColor: Color(uiColor: .mvmBlack),
enabledBorderColor: Color(uiColor: .mvmBlack),
disabledFillColor: Color(uiColor: .mvmWhite),
disabledTextColor: Color(uiColor: .mvmCoolGray6),
disabledBorderColor: Color(uiColor: .mvmCoolGray6),
enabledFillColor_inverted: Color(uiColor: .mvmBlack),
enabledTextColor_inverted: Color(uiColor: .mvmWhite),
enabledBorderColor_inverted: Color(uiColor: .mvmWhite),
disabledFillColor_inverted: Color(uiColor: .mvmWhite),
disabledTextColor_inverted: Color(uiColor: .mvmCoolGray6),
disabledBorderColor_inverted: Color(uiColor: .mvmCoolGray6))
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
@ -50,7 +82,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
} }
/// Temporary binding mechanism for the view to update on enable changes. /// Temporary binding mechanism for the view to update on enable changes.
public var updateUI: (() -> ())? public var updateUI: ActionBlock?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializers // MARK: - Initializers
@ -80,18 +112,13 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case backgroundColor case backgroundColor
case isInverted = "inverted"
case title case title
case inverted
case action case action
case enabled case enabled
case style case style
case size case size
case fillColor case facade
case textColor
case borderColor
case disabledFillColor
case disabledTextColor
case disabledBorderColor
case groupName case groupName
} }
@ -102,10 +129,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
required public init(from decoder: Decoder) throws { required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let isInverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
self.isInverted = isInverted
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
title = try typeContainer.decode(String.self, forKey: .title) title = try typeContainer.decode(String.self, forKey: .title)
action = try typeContainer.decodeModel(codingKey: .action) action = try typeContainer.decodeModel(codingKey: .action)
@ -126,30 +149,33 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
self.enabled = enabled self.enabled = enabled
} }
fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor) if let facade = try typeContainer.decodeIfPresent(Facade.self, forKey: .facade) {
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) self.facade = facade
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
disabledFillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledFillColor) switch style {
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) case .primary:
disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) primaryFacade = facade
case .secondary:
secondaryFacade = facade
}
}
if let isInverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.isInverted = isInverted
}
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self) var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName) try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(title, forKey: .title) try container.encode(title, forKey: .title)
try container.encode(isInverted, forKey: .isInverted) try container.encode(isInverted, forKey: .inverted)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeModel(action, forKey: .action)
try container.encode(enabled, forKey: .enabled) try container.encode(enabled, forKey: .enabled)
try container.encodeModel(action, forKey: .action)
try container.encodeIfPresent(facade, forKey: .facade)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(style, forKey: .style) try container.encodeIfPresent(style, forKey: .style)
try container.encodeIfPresent(size, forKey: .size) try container.encodeIfPresent(size, forKey: .size)
try container.encodeIfPresent(fillColor, forKey: .fillColor)
try container.encodeIfPresent(textColor, forKey: .textColor)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor)
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(groupName, forKey: .groupName)
} }
} }

View File

@ -8,78 +8,93 @@
import UIKit import UIKit
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
// Used to size the button. //--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
/// Used to size the button.
var size = MVMCoreUIUtility.getWidth() var size = MVMCoreUIUtility.getWidth()
var buttonModel: ButtonModel? { var buttonModel: ButtonModel? {
get { return model as? ButtonModel } get { return model as? ButtonModel }
} }
// Need to re-style on set. /// Need to re-style on set.
open override var isEnabled: Bool { open override var isEnabled: Bool {
didSet { didSet { style() }
style()
}
} }
private enum ButtonHeight: CGFloat { private enum Height: CGFloat {
case tiny = 20 case tiny = 20
case standard = 42 case standard = 42
} }
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
/// The primary styling for a button. Should be used for main buttons /// The primary styling for a button. Should be used for main buttons
public func stylePrimary() { public func stylePrimary() {
setTitleColor(.white, for: .normal)
setTitleColor(.white, for: .disabled) buttonModel?.style = .primary
setTitleColor(buttonModel?.facade?.enabled.text ?? .mvmWhite, for: .normal)
setTitleColor(buttonModel?.facade?.disabled.text ?? .mvmWhite, for: .disabled)
layer.borderWidth = 0 layer.borderWidth = 0
if isEnabled { backgroundColor = isEnabled ? buttonModel?.facade?.enabled.fill ?? .mvmBlack : buttonModel?.facade?.enabled.fill ?? .mvmCoolGray6
backgroundColor = .black
} else {
backgroundColor = .mvmCoolGray6
}
} }
/// The secondary styling for a button. Should be used for secondary buttons /// The secondary styling for a button. Should be used for secondary buttons
public func styleSecondary() { public func styleSecondary() {
setTitleColor(.black, for: .normal)
setTitleColor(.mvmCoolGray6, for: .disabled) buttonModel?.style = .secondary
setTitleColor(buttonModel?.facade?.enabled.text ?? .mvmBlack, for: .normal)
setTitleColor(buttonModel?.facade?.disabled.text ?? .mvmCoolGray6, for: .disabled)
backgroundColor = .clear backgroundColor = .clear
layer.borderWidth = 1 layer.borderWidth = 1
if isEnabled { if isEnabled {
layer.borderColor = UIColor.black.cgColor layer.borderColor = buttonModel?.facade?.enabled.border?.cgColor ?? UIColor.mvmBlack.cgColor
} else { } else {
layer.borderColor = UIColor.mvmCoolGray6.cgColor layer.borderColor = buttonModel?.facade?.enabled.border?.cgColor ?? UIColor.mvmCoolGray6.cgColor
} }
} }
/// Styles the button based on the model style /// Styles the button based on the model style
private func style() { private func style() {
switch buttonModel?.style { switch buttonModel?.style {
case .secondary: case .secondary:
styleSecondary() styleSecondary()
default: default:
stylePrimary() stylePrimary()
} }
if let titleColor = buttonModel?.textColor {
setTitleColor(titleColor.uiColor, for: .normal) if let titleColor = buttonModel?.facade?.enabled.text {
setTitleColor(titleColor, for: .normal)
} }
if let disabledTitleColor = buttonModel?.disabledTextColor {
setTitleColor(disabledTitleColor.uiColor, for: .disabled) if let disabledTitleColor = buttonModel?.facade?.disabled.text {
setTitleColor(disabledTitleColor, for: .disabled)
} }
if isEnabled { if isEnabled {
if let fillColor = buttonModel?.fillColor { if let fillColor = buttonModel?.facade?.enabled.fill {
backgroundColor = fillColor.uiColor backgroundColor = fillColor
} }
if let borderColor = buttonModel?.borderColor {
if let borderColor = buttonModel?.facade?.enabled.border {
layer.borderWidth = 1 layer.borderWidth = 1
layer.borderColor = borderColor.cgColor layer.borderColor = borderColor.cgColor
} }
} else { } else {
if let fillColor = buttonModel?.disabledFillColor { if let fillColor = buttonModel?.facade?.disabled.fill {
backgroundColor = fillColor.uiColor backgroundColor = fillColor
} }
if let borderColor = buttonModel?.disabledBorderColor {
if let borderColor = buttonModel?.facade?.disabledBorderColor {
layer.borderWidth = 1 layer.borderWidth = 1
layer.borderColor = borderColor.cgColor layer.borderColor = borderColor.cgColor
} }
@ -87,7 +102,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
} }
private func getInnerPadding() -> CGFloat { private func getInnerPadding() -> CGFloat {
return getHeight() / 2.0 return getHeight() / 2
} }
private func getHeight() -> CGFloat { private func getHeight() -> CGFloat {
@ -95,30 +110,38 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
} }
public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat { public static func getHeight(for buttonSize: ButtonSize?, size: CGFloat) -> CGFloat {
switch buttonSize { switch buttonSize {
case .tiny: case .tiny:
return MFSizeObject(standardSize: ButtonHeight.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? ButtonHeight.tiny.rawValue return MFSizeObject(standardSize: Height.tiny.rawValue, standardiPadPortraitSize: 34, iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? Height.tiny.rawValue
default: default:
return MFSizeObject(standardSize: ButtonHeight.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? ButtonHeight.standard.rawValue return MFSizeObject(standardSize: Height.standard.rawValue, standardiPadPortraitSize: 46, iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? Height.standard.rawValue
} }
} }
private func getMinimumWidth() -> CGFloat { private func getMinimumWidth() -> CGFloat {
switch buttonModel?.size { switch buttonModel?.size {
case .tiny: case .tiny:
return MFSizeObject(standardSize: 49.0, standardiPadPortraitSize: 90.0, iPadProLandscapeSize: 135.0)?.getValueBased(onSize: size) ?? 49.0 return MFSizeObject(standardSize: 49, standardiPadPortraitSize: 90, iPadProLandscapeSize: 135)?.getValueBased(onSize: size) ?? 49
default: default:
return 151.0 return 151
} }
} }
open override var intrinsicContentSize: CGSize { open override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize let size = super.intrinsicContentSize
let width = size.width + (2 * getInnerPadding()) let width = size.width + (2 * getInnerPadding())
return CGSize(width: max(width, getMinimumWidth()), height: getHeight()) return CGSize(width: max(width, getMinimumWidth()), height: getHeight())
} }
// MARK: - MoleculeViewProtocol //--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
// The button will get styled in the enable check in super. // The button will get styled in the enable check in super.
super.set(with: model, delegateObject, additionalData) super.set(with: model, delegateObject, additionalData)
@ -132,6 +155,8 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
}) })
} }
style()
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
} }
@ -139,22 +164,26 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
PillButton.getHeight(for: (model as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth()) PillButton.getHeight(for: (model as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth())
} }
// MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
self.size = size self.size = size
invalidateIntrinsicContentSize() invalidateIntrinsicContentSize()
switch buttonModel?.size { switch buttonModel?.size {
case .tiny: case .tiny:
titleLabel?.font = MFFonts.mfFont75Bd(11 * (intrinsicContentSize.height / ButtonHeight.tiny.rawValue)) titleLabel?.font = MFFonts.mfFont75Bd(11 * (intrinsicContentSize.height / Height.tiny.rawValue))
default: default:
titleLabel?.font = MFFonts.mfFont75Bd(13 * (intrinsicContentSize.height / ButtonHeight.standard.rawValue)) titleLabel?.font = MFFonts.mfFont75Bd(13 * (intrinsicContentSize.height / Height.standard.rawValue))
} }
layer.cornerRadius = getInnerPadding() layer.cornerRadius = getInnerPadding()
} }
open override func setupView() { open override func setupView() {
super.setupView() super.setupView()
titleLabel?.numberOfLines = 1 titleLabel?.numberOfLines = 1
titleLabel?.lineBreakMode = .byTruncatingTail titleLabel?.lineBreakMode = .byTruncatingTail
titleLabel?.textAlignment = .center titleLabel?.textAlignment = .center
@ -162,7 +191,10 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
stylePrimary() stylePrimary()
} }
//--------------------------------------------------
// MARK: - MVMCoreUIViewConstrainingProtocol // MARK: - MVMCoreUIViewConstrainingProtocol
//--------------------------------------------------
open func horizontalAlignment() -> UIStackView.Alignment { open func horizontalAlignment() -> UIStackView.Alignment {
return .center return .center
} }

View File

@ -9,11 +9,24 @@
import UIKit import UIKit
@objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol { @objcMembers open class TwoButtonView: View, MVMCoreUIViewConstrainingProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open var primaryButton: PillButton = PillButton() open var primaryButton: PillButton = PillButton()
open var secondaryButton: PillButton = PillButton() open var secondaryButton: PillButton = PillButton()
private var stack = UIStackView() private var stack = UIStackView()
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
private var equalWidthConstraint: NSLayoutConstraint? private var equalWidthConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public init() { public init() {
super.init(frame: .zero) super.init(frame: .zero)
} }
@ -26,12 +39,15 @@ import UIKit
super.init(frame: frame) super.init(frame: frame)
} }
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
public func setDefault() { public func setDefault() {
primaryButton.stylePrimary() primaryButton.stylePrimary()
secondaryButton.styleSecondary() secondaryButton.styleSecondary()
} }
// MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) { open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
self.primaryButton.updateView(size) self.primaryButton.updateView(size)
@ -52,58 +68,68 @@ import UIKit
equalWidthConstraint?.isActive = true equalWidthConstraint?.isActive = true
} }
//--------------------------------------------------
// MARK: - Stack Manipulation // MARK: - Stack Manipulation
//--------------------------------------------------
public func showPrimaryButton() { public func showPrimaryButton() {
if !stack.arrangedSubviews.contains(primaryButton) { if !stack.arrangedSubviews.contains(primaryButton) {
stack.addArrangedSubview(primaryButton) stack.addArrangedSubview(primaryButton)
primaryButton.isHidden = false primaryButton.isHidden = false
} }
if secondaryButton.superview != nil { if secondaryButton.superview != nil {
equalWidthConstraint?.isActive = true equalWidthConstraint?.isActive = true
} }
} }
public func showSecondaryButton() { public func showSecondaryButton() {
if !stack.arrangedSubviews.contains(secondaryButton) { if !stack.arrangedSubviews.contains(secondaryButton) {
stack.insertArrangedSubview(secondaryButton, at: 0) stack.insertArrangedSubview(secondaryButton, at: 0)
secondaryButton.isHidden = false secondaryButton.isHidden = false
} }
if primaryButton.superview != nil { if primaryButton.superview != nil {
equalWidthConstraint?.isActive = true equalWidthConstraint?.isActive = true
} }
} }
public func hidePrimaryButton() { public func hidePrimaryButton() {
if primaryButton.superview != nil { if primaryButton.superview != nil {
stack.removeArrangedSubview(primaryButton) stack.removeArrangedSubview(primaryButton)
primaryButton.isHidden = true primaryButton.isHidden = true
} }
equalWidthConstraint?.isActive = false equalWidthConstraint?.isActive = false
} }
public func hideSecondaryButton() { public func hideSecondaryButton() {
if secondaryButton.superview != nil { if secondaryButton.superview != nil {
stack.removeArrangedSubview(secondaryButton) stack.removeArrangedSubview(secondaryButton)
secondaryButton.isHidden = true secondaryButton.isHidden = true
} }
equalWidthConstraint?.isActive = false equalWidthConstraint?.isActive = false
} }
//--------------------------------------------------
// MARK: - MoleculeViewProtocol // MARK: - MoleculeViewProtocol
//--------------------------------------------------
open override func reset() { open override func reset() {
super.reset() super.reset()
setDefault() setDefault()
} }
// MARK: - MVMCoreUIViewConstrainingProtocol
open func horizontalAlignment() -> UIStackView.Alignment {
return .center
}
// MARK: - MoleculeViewProtocol
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
guard let model = model as? TwoButtonViewModel, guard let model = model as? TwoButtonViewModel,
let buttonModel = model.primaryButton ?? model.secondaryButton else { return 0 } let buttonModel = model.primaryButton ?? model.secondaryButton
else { return 0 }
return PillButton.estimatedHeight(with: buttonModel, delegateObject) return PillButton.estimatedHeight(with: buttonModel, delegateObject)
} }
@ -118,6 +144,7 @@ import UIKit
} else { } else {
hideSecondaryButton() hideSecondaryButton()
} }
if let primaryModel = model.primaryButton { if let primaryModel = model.primaryButton {
showPrimaryButton() showPrimaryButton()
primaryButton.set(with: primaryModel, delegateObject, additionalData) primaryButton.set(with: primaryModel, delegateObject, additionalData)
@ -125,4 +152,11 @@ import UIKit
hidePrimaryButton() hidePrimaryButton()
} }
} }
//--------------------------------------------------
// MARK: - MVMCoreUIViewConstrainingProtocol
//--------------------------------------------------
open func horizontalAlignment() -> UIStackView.Alignment {
return .center
}
} }

View File

@ -8,12 +8,21 @@
import UIKit import UIKit
public class TwoButtonViewModel: MoleculeModelProtocol { public class TwoButtonViewModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "twoButtonView" public static var identifier: String = "twoButtonView"
public var backgroundColor: Color? public var backgroundColor: Color?
public var primaryButton: ButtonModel? public var primaryButton: ButtonModel?
public var secondaryButton: ButtonModel? public var secondaryButton: ButtonModel?
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case moleculeName case moleculeName
case backgroundColor case backgroundColor
@ -21,20 +30,25 @@ public class TwoButtonViewModel: MoleculeModelProtocol {
case secondaryButton case secondaryButton
} }
//--------------------------------------------------
// MARK: - Initialzer
//--------------------------------------------------
public init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) { public init(_ primaryButton: ButtonModel?, _ secondaryButton: ButtonModel?) {
self.primaryButton = primaryButton self.primaryButton = primaryButton
self.secondaryButton = secondaryButton self.secondaryButton = secondaryButton
} }
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws { required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton) primaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .primaryButton)
secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton) secondaryButton = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .secondaryButton)
// Default value secondaryButton?.style = .secondary
if secondaryButton?.style == nil {
secondaryButton?.style = .secondary
}
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {

View File

@ -12,6 +12,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Stored Properties // MARK: - Stored Properties
//-------------------------------------------------- //--------------------------------------------------
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]?
var observer: NSKeyValueObservation? var observer: NSKeyValueObservation?

View File

@ -8,24 +8,39 @@
import Foundation import Foundation
@objcMembers public class TemplateModel: MVMControllerModelProtocol { @objcMembers public class TemplateModel: MVMControllerModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public class var identifier: String { public class var identifier: String {
return "" return ""
} }
public var pageType: String public var pageType: String
public var template: String { public var template: String {
// Although this is done in the extension, it is needed for the encoding. // Although this is done in the extension, it is needed for the encoding.
return Self.identifier return Self.identifier
} }
public var backgroundColor: Color? public var backgroundColor: Color?
public var screenHeading: String? public var screenHeading: String?
public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)? public var navigationItem: (NavigationItemModelProtocol & MoleculeModelProtocol)?
public var formRules: [FormGroupRule]? public var formRules: [FormGroupRule]?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(pageType: String) { public init(pageType: String) {
self.pageType = pageType self.pageType = pageType
} }
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case pageType case pageType
case template case template
@ -35,6 +50,10 @@ import Foundation
case navigationItem case navigationItem
} }
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws { required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self) let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
pageType = try typeContainer.decode(String.self, forKey: .pageType) pageType = try typeContainer.decode(String.self, forKey: .pageType)

View File

@ -24,25 +24,25 @@ import UIKit
open override func viewForTop() -> UIView? { open override func viewForTop() -> UIView? {
guard let headerModel = templateModel?.header, guard let headerModel = templateModel?.header,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar) else { let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar)
return nil else { return nil }
}
return molecule return molecule
} }
open override func viewForMiddle() -> UIView? { open override func viewForMiddle() -> UIView? {
guard let middleModel = templateModel?.middle, guard let middleModel = templateModel?.middle,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(middleModel, delegateObject: delegateObjectIVar) else { let molecule = MoleculeObjectMapping.shared()?.createMolecule(middleModel, delegateObject: delegateObjectIVar)
return nil else { return nil }
}
return molecule return molecule
} }
override open func viewForBottom() -> UIView? { override open func viewForBottom() -> UIView? {
guard let footerModel = templateModel?.footer, guard let footerModel = templateModel?.footer,
let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar) else { let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar)
return nil else { return nil }
}
return molecule return molecule
} }

View File

@ -257,7 +257,7 @@ import UIKit
viewRespectsSystemMinimumLayoutMargins = false viewRespectsSystemMinimumLayoutMargins = false
// Presents from the bottom. // Presents from the bottom.
modalPresentationStyle = MVMCoreGetterUtility.isOnIPad() ? UIModalPresentationStyle.formSheet : UIModalPresentationStyle.overCurrentContext modalPresentationStyle = MVMCoreGetterUtility.isOnIPad() ? .formSheet : .overCurrentContext
// Create the default delegate object. // Create the default delegate object.
delegateObjectIVar = MVMCoreUIDelegateObject.create(withDelegateForAll: self) delegateObjectIVar = MVMCoreUIDelegateObject.create(withDelegateForAll: self)

View File

@ -0,0 +1,177 @@
//
// Facade.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 4/30/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?)
public class Facade: Codable {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var isInverted: Bool = false
public lazy var enabled: FacadeElements = (fill: enabled_fillColor(),
text: enabled_textColor(),
border: enabled_borderColor())
public lazy var disabled: FacadeElements = (fill: disabled_fillColor(),
text: disabled_textColor(),
border: disabled_borderColor())
public var backgroundColor_standard: Color?
public var backgroundColor_inverted: Color?
public var enabledFillColor: Color?
public var enabledTextColor: Color?
public var enabledBorderColor: Color?
public var enabledFillColor_inverted: Color?
public var enabledTextColor_inverted: Color?
public var enabledBorderColor_inverted: Color?
public var disabledFillColor: Color?
public var disabledTextColor: Color?
public var disabledBorderColor: Color?
public var disabledFillColor_inverted: Color?
public var disabledTextColor_inverted: Color?
public var disabledBorderColor_inverted: Color?
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(isInverted: Bool = false,
backgroundColor_standard: Color? = nil,
backgroundColor_inverted: Color? = nil,
enabledFillColor: Color? = nil,
enabledTextColor: Color? = nil,
enabledBorderColor: Color? = nil,
disabledFillColor: Color? = nil,
disabledTextColor: Color? = nil,
disabledBorderColor: Color? = nil,
enabledFillColor_inverted: Color? = nil,
enabledTextColor_inverted: Color? = nil,
enabledBorderColor_inverted: Color? = nil,
disabledFillColor_inverted: Color? = nil,
disabledTextColor_inverted: Color? = nil,
disabledBorderColor_inverted: Color? = nil) {
self.isInverted = isInverted
self.backgroundColor_standard = backgroundColor_standard
self.backgroundColor_inverted = backgroundColor_inverted
self.enabledFillColor = enabledFillColor
self.enabledTextColor = enabledTextColor
self.enabledBorderColor = enabledBorderColor
self.disabledFillColor = disabledFillColor
self.disabledTextColor = disabledTextColor
self.disabledBorderColor = disabledBorderColor
self.enabledFillColor_inverted = enabledFillColor_inverted
self.enabledTextColor_inverted = enabledTextColor_inverted
self.enabledBorderColor_inverted = enabledBorderColor_inverted
self.disabledFillColor_inverted = disabledFillColor_inverted
self.disabledTextColor_inverted = disabledTextColor_inverted
self.disabledBorderColor_inverted = disabledBorderColor_inverted
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
public func backgroundColor() -> UIColor? {
return (isInverted ? backgroundColor_inverted : backgroundColor_standard)?.uiColor
}
public func enabled_fillColor() -> UIColor? {
return (isInverted ? enabledFillColor_inverted : enabledFillColor)?.uiColor
}
public func enabled_textColor() -> UIColor? {
return (isInverted ? enabledTextColor_inverted : enabledTextColor)?.uiColor
}
public func enabled_borderColor() -> UIColor? {
return (isInverted ? enabledBorderColor_inverted : enabledBorderColor)?.uiColor
}
public func disabled_fillColor() -> UIColor? {
return (isInverted ? disabledFillColor_inverted : disabledFillColor)?.uiColor
}
public func disabled_textColor() -> UIColor? {
return (isInverted ? disabledTextColor_inverted : disabledTextColor)?.uiColor
}
public func disabled_borderColor() -> UIColor? {
return (isInverted ? disabledBorderColor_inverted : disabledBorderColor)?.uiColor
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case backgroundColor_standard
case backgroundColor_inverted
case enabledFillColor
case enabledTextColor
case enabledBorderColor
case enabledFillColor_inverted
case enabledTextColor_inverted
case enabledBorderColor_inverted
case disabledFillColor
case disabledTextColor
case disabledBorderColor
case disabledFillColor_inverted
case disabledTextColor_inverted
case disabledBorderColor_inverted
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor_standard = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_standard)
backgroundColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor_inverted)
enabledFillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledFillColor)
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
enabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledBorderColor)
enabledFillColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledFillColor_inverted)
enabledTextColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor_inverted)
enabledBorderColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledBorderColor_inverted)
disabledFillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledFillColor)
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor)
disabledFillColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledFillColor_inverted)
disabledTextColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor_inverted)
disabledBorderColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor_inverted)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor_standard, forKey: .backgroundColor_standard)
try container.encodeIfPresent(backgroundColor_inverted, forKey: .backgroundColor_inverted)
try container.encodeIfPresent(enabledFillColor, forKey: .enabledFillColor)
try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor)
try container.encodeIfPresent(enabledBorderColor, forKey: .enabledBorderColor)
try container.encodeIfPresent(enabledFillColor_inverted, forKey: .enabledFillColor_inverted)
try container.encodeIfPresent(enabledTextColor_inverted, forKey: .enabledTextColor_inverted)
try container.encodeIfPresent(enabledBorderColor_inverted, forKey: .enabledBorderColor_inverted)
try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor)
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor)
try container.encodeIfPresent(disabledFillColor_inverted, forKey: .disabledFillColor_inverted)
try container.encodeIfPresent(disabledTextColor_inverted, forKey: .disabledTextColor_inverted)
try container.encodeIfPresent(disabledBorderColor_inverted, forKey: .disabledBorderColor_inverted)
}
}