Merge branch 'feature/develop_mvp_3' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui into feature/3.0-TitleLockup
This commit is contained in:
commit
7554a718b5
@ -126,6 +126,7 @@
|
|||||||
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
|
0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB423FF18D2004C5109 /* Arrow.swift */; };
|
||||||
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; };
|
0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB623FF18E9004C5109 /* ArrowModel.swift */; };
|
||||||
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */; };
|
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */; };
|
||||||
|
187FEB2A2844D2A600BF29C2 /* VDSFormControlsTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 187FEB292844D2A600BF29C2 /* VDSFormControlsTokens.xcframework */; };
|
||||||
1D6D258826899B0C00DEBB08 /* ImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */; };
|
1D6D258826899B0C00DEBB08 /* ImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */; };
|
||||||
1D6D258926899B0C00DEBB08 /* ImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258726899B0B00DEBB08 /* ImageButton.swift */; };
|
1D6D258926899B0C00DEBB08 /* ImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6D258726899B0B00DEBB08 /* ImageButton.swift */; };
|
||||||
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */; };
|
||||||
@ -350,7 +351,7 @@
|
|||||||
D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */; };
|
D22479942316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */; };
|
||||||
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */; };
|
D22479962316AF6E003FCCF9 /* HeadlineBodyLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */; };
|
||||||
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; };
|
D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */; };
|
||||||
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* TemplateModel.swift */; };
|
D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */; };
|
||||||
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
|
D22D8395241FB41200D3DF69 /* UIStackView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */; };
|
||||||
D23118B325124E18001C8440 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23118B225124E18001C8440 /* Notification.swift */; };
|
D23118B325124E18001C8440 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23118B225124E18001C8440 /* Notification.swift */; };
|
||||||
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; };
|
D2351C7A24A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */; };
|
||||||
@ -716,6 +717,7 @@
|
|||||||
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
|
0AE98BB423FF18D2004C5109 /* Arrow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arrow.swift; sourceTree = "<group>"; };
|
||||||
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = "<group>"; };
|
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrowModel.swift; sourceTree = "<group>"; };
|
||||||
0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIUtility+Extension.swift"; sourceTree = "<group>"; };
|
0AF60F0826B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIUtility+Extension.swift"; sourceTree = "<group>"; };
|
||||||
|
187FEB292844D2A600BF29C2 /* VDSFormControlsTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSFormControlsTokens.xcframework; path = ../SharedFrameworks/VDSFormControlsTokens.xcframework; sourceTree = "<group>"; };
|
||||||
1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButtonModel.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift; sourceTree = SOURCE_ROOT; };
|
1D6D258626899B0B00DEBB08 /* ImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButtonModel.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift; sourceTree = SOURCE_ROOT; };
|
||||||
1D6D258726899B0B00DEBB08 /* ImageButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButton.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButton.swift; sourceTree = SOURCE_ROOT; };
|
1D6D258726899B0B00DEBB08 /* ImageButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ImageButton.swift; path = MVMCoreUI/Atomic/Atoms/Buttons/ImageButton.swift; sourceTree = SOURCE_ROOT; };
|
||||||
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
279B1568242BBC2F00921D6C /* ActionModelAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionModelAdapter.swift; sourceTree = "<group>"; };
|
||||||
@ -940,7 +942,7 @@
|
|||||||
D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutConstraintExtension.swift; sourceTree = "<group>"; };
|
D22479932316AE5E003FCCF9 /* NSLayoutConstraintExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLayoutConstraintExtension.swift; sourceTree = "<group>"; };
|
||||||
D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyLink.swift; sourceTree = "<group>"; };
|
D22479952316AF6D003FCCF9 /* HeadlineBodyLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyLink.swift; sourceTree = "<group>"; };
|
||||||
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = "<group>"; };
|
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccordionMoleculeTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
D22D8392241C27B100D3DF69 /* TemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModel.swift; sourceTree = "<group>"; };
|
D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTemplateModel.swift; sourceTree = "<group>"; };
|
||||||
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
|
D22D8394241FB41200D3DF69 /* UIStackView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+Extension.swift"; sourceTree = "<group>"; };
|
||||||
D23118B225124E18001C8440 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
|
D23118B225124E18001C8440 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
|
||||||
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
D2351C7924A4D433007DF0BC /* ListRightVariableToggleAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableToggleAllTextAndLinksModel.swift; sourceTree = "<group>"; };
|
||||||
@ -1193,6 +1195,7 @@
|
|||||||
D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */,
|
D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */,
|
||||||
AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */,
|
AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */,
|
||||||
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */,
|
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */,
|
||||||
|
187FEB2A2844D2A600BF29C2 /* VDSFormControlsTokens.xcframework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -1992,7 +1995,7 @@
|
|||||||
D29DF0DF21E418B2003B2FB9 /* Templates */ = {
|
D29DF0DF21E418B2003B2FB9 /* Templates */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D22D8392241C27B100D3DF69 /* TemplateModel.swift */,
|
D22D8392241C27B100D3DF69 /* BaseTemplateModel.swift */,
|
||||||
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */,
|
D2092356244FA1EF0044AD09 /* ThreeLayerModelBase.swift */,
|
||||||
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
|
014AA72823C5059B006F3E93 /* StackPageTemplateModel.swift */,
|
||||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
||||||
@ -2025,6 +2028,7 @@
|
|||||||
D29DF0E421E4F3C7003B2FB9 /* Frameworks */ = {
|
D29DF0E421E4F3C7003B2FB9 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
187FEB292844D2A600BF29C2 /* VDSFormControlsTokens.xcframework */,
|
||||||
AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */,
|
AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */,
|
||||||
D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */,
|
D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */,
|
||||||
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */,
|
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */,
|
||||||
@ -3085,7 +3089,7 @@
|
|||||||
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */,
|
D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */,
|
||||||
D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */,
|
D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */,
|
||||||
012A88F123985E0100FE3DA1 /* Color.swift in Sources */,
|
012A88F123985E0100FE3DA1 /* Color.swift in Sources */,
|
||||||
D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */,
|
D22D8393241C27B100D3DF69 /* BaseTemplateModel.swift in Sources */,
|
||||||
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
||||||
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */,
|
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */,
|
||||||
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */,
|
D23A8FFB26123189007E14CE /* PageBehaviorModelProtocol.swift in Sources */,
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import VDSColorTokens
|
||||||
|
|
||||||
public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?)
|
public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?)
|
||||||
|
|
||||||
@ -17,12 +18,12 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
//Making static property as class property so that subclasses can override getter function of the property
|
//Making static property as class property so that subclasses can override getter function of the property
|
||||||
open class var identifier: String { "button" }
|
open class var identifier: String { "button" }
|
||||||
public var backgroundColor: Color?
|
|
||||||
public var accessibilityIdentifier: String?
|
public var accessibilityIdentifier: String?
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
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 width: CGFloat?
|
||||||
public var style: Styler.Button.Style? {
|
public var style: Styler.Button.Style? {
|
||||||
didSet {
|
didSet {
|
||||||
guard let style = style else { return }
|
guard let style = style else { return }
|
||||||
@ -57,6 +58,20 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
public var disabledTextColor_inverted: Color?
|
public var disabledTextColor_inverted: Color?
|
||||||
public var disabledBorderColor_inverted: Color?
|
public var disabledBorderColor_inverted: Color?
|
||||||
|
|
||||||
|
private var _backgroundColor: Color?
|
||||||
|
public var backgroundColor: Color? {
|
||||||
|
get {
|
||||||
|
if let backgroundColor = _backgroundColor { return backgroundColor }
|
||||||
|
if inverted {
|
||||||
|
return enabled ? enabledFillColor_inverted : disabledFillColor_inverted
|
||||||
|
}
|
||||||
|
return enabled ? enabledFillColor : disabledFillColor
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
_backgroundColor = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -70,18 +85,21 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
public init(with title: String, action: ActionModelProtocol) {
|
public init(with title: String, action: ActionModelProtocol) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.action = action
|
self.action = action
|
||||||
|
setFacade(by: .primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(secondaryButtonWith title: String, action: ActionModelProtocol) {
|
public init(secondaryButtonWith title: String, action: ActionModelProtocol) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.action = action
|
self.action = action
|
||||||
style = .secondary
|
style = .secondary
|
||||||
|
setFacade(by: .secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(primaryButtonWith title: String, action: ActionModelProtocol) {
|
public init(primaryButtonWith title: String, action: ActionModelProtocol) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.action = action
|
self.action = action
|
||||||
style = .primary
|
style = .primary
|
||||||
|
setFacade(by: .primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -114,40 +132,30 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
|
|
||||||
/// Defines the default appearance for the primary style.
|
/// Defines the default appearance for the primary style.
|
||||||
func setPrimaryFacade() {
|
func setPrimaryFacade() {
|
||||||
|
enabledFillColor = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
|
enabledTextColor = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
|
disabledFillColor = Color(uiColor: VDSColor.interactiveDisabledOnlight)
|
||||||
|
disabledTextColor = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
|
|
||||||
if enabledFillColor == nil && enabledTextColor == nil {
|
enabledFillColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
enabledFillColor = Color(uiColor: .mvmBlack)
|
enabledTextColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
enabledTextColor = Color(uiColor: .mvmWhite)
|
disabledFillColor_inverted = Color(uiColor: VDSColor.interactiveDisabledOndark)
|
||||||
}
|
disabledTextColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
|
|
||||||
if disabledFillColor == nil && disabledTextColor == nil {
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the default appearance for the Secondary style.
|
/// Defines the default appearance for the Secondary style.
|
||||||
func setSecondaryFacade() {
|
func setSecondaryFacade() {
|
||||||
|
enabledTextColor = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
|
enabledFillColor = Color(uiColor: UIColor.clear)
|
||||||
|
enabledBorderColor = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
|
disabledTextColor = Color(uiColor: VDSColor.interactiveDisabledOnlight)
|
||||||
|
disabledBorderColor = Color(uiColor: VDSColor.interactiveDisabledOnlight)
|
||||||
|
|
||||||
if enabledTextColor == nil && enabledBorderColor == nil {
|
enabledTextColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
enabledTextColor = Color(uiColor: .mvmBlack)
|
enabledFillColor_inverted = Color(uiColor: UIColor.clear)
|
||||||
enabledBorderColor = Color(uiColor: .mvmBlack)
|
enabledBorderColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
}
|
disabledTextColor_inverted = Color(uiColor: VDSColor.interactiveDisabledOndark)
|
||||||
|
disabledBorderColor_inverted = Color(uiColor: VDSColor.interactiveDisabledOndark)
|
||||||
if disabledTextColor == nil && disabledBorderColor == nil {
|
|
||||||
disabledTextColor = Color(uiColor: .mvmCoolGray6)
|
|
||||||
disabledBorderColor = Color(uiColor: .mvmCoolGray6)
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledTextColor_inverted = Color(uiColor: .mvmWhite)
|
|
||||||
enabledBorderColor_inverted = Color(uiColor: .mvmWhite)
|
|
||||||
disabledTextColor_inverted = Color(uiColor: .mvmCoolGray6)
|
|
||||||
disabledBorderColor_inverted = Color(uiColor: .mvmCoolGray6)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setFacade(by style: Styler.Button.Style) {
|
public func setFacade(by style: Styler.Button.Style) {
|
||||||
@ -183,6 +191,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
case disabledFillColor
|
case disabledFillColor
|
||||||
case disabledTextColor
|
case disabledTextColor
|
||||||
case disabledBorderColor
|
case disabledBorderColor
|
||||||
|
case width
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -192,15 +201,21 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
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)
|
|
||||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||||
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)
|
||||||
|
|
||||||
|
if let style = decoder.context?.value(forKey: CodingKeys.style.stringValue) as? Styler.Button.Style{
|
||||||
|
self.style = style
|
||||||
|
setFacade(by: style)
|
||||||
|
}
|
||||||
|
|
||||||
if let style = try typeContainer.decodeIfPresent(Styler.Button.Style.self, forKey: .style) {
|
if let style = try typeContainer.decodeIfPresent(Styler.Button.Style.self, forKey: .style) {
|
||||||
self.style = style
|
self.style = style
|
||||||
setFacade(by: style)
|
setFacade(by: style)
|
||||||
|
} else {
|
||||||
|
setFacade(by: .primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let size = try typeContainer.decodeIfPresent(Styler.Button.Size.self, forKey: .size) {
|
if let size = try typeContainer.decodeIfPresent(Styler.Button.Size.self, forKey: .size) {
|
||||||
@ -242,6 +257,9 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) {
|
if let disabledBorderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledBorderColor) {
|
||||||
self.disabledBorderColor = disabledBorderColor
|
self.disabledBorderColor = disabledBorderColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
|
width = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .width)
|
||||||
}
|
}
|
||||||
|
|
||||||
open func encode(to encoder: Encoder) throws {
|
open func encode(to encoder: Encoder) throws {
|
||||||
@ -251,7 +269,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
try container.encode(inverted, forKey: .inverted)
|
try container.encode(inverted, forKey: .inverted)
|
||||||
try container.encodeModel(action, forKey: .action)
|
try container.encodeModel(action, forKey: .action)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
try container.encodeIfPresent(enabledFillColor, forKey: .fillColor)
|
try container.encodeIfPresent(enabledFillColor, forKey: .fillColor)
|
||||||
@ -263,5 +281,6 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat
|
|||||||
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(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
try container.encodeIfPresent(width, forKey: .width)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import VDSColorTokens
|
||||||
|
|
||||||
@objcMembers open class Link: Button {
|
@objcMembers open class Link: Button {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -28,8 +28,8 @@ import UIKit
|
|||||||
// x should be according to the text, not the button
|
// x should be according to the text, not the button
|
||||||
let x = textRect.origin.x
|
let x = textRect.origin.x
|
||||||
|
|
||||||
// Line is 1 point below the text
|
// Line is 0 point below the text
|
||||||
let y = textRect.origin.y + textRect.size.height + 1
|
let y = textRect.origin.y + textRect.size.height
|
||||||
|
|
||||||
context.move(to: CGPoint(x: x, y: y))
|
context.move(to: CGPoint(x: x, y: y))
|
||||||
context.addLine(to: CGPoint(x: x + textRect.size.width, y: y))
|
context.addLine(to: CGPoint(x: x + textRect.size.width, y: y))
|
||||||
@ -38,7 +38,7 @@ import UIKit
|
|||||||
|
|
||||||
open override var intrinsicContentSize: CGSize {
|
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)
|
return CGSize(width: size.width, height: size.height + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -56,7 +56,9 @@ import UIKit
|
|||||||
}
|
}
|
||||||
setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal)
|
setTitleColor((model.inverted ? model.enabledColor_inverted : model.enabledColor).uiColor, for: .normal)
|
||||||
setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled)
|
setTitleColor((model.inverted ? model.disabledColor_inverted : model.disabledColor).uiColor, for: .disabled)
|
||||||
|
setTitleColor((model.inverted ? model.activeColor_inverted : model.activeColor).uiColor, for: .highlighted)
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
|
titleLabel?.font = model.getFont(model.size)
|
||||||
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,21 +70,15 @@ extension Link {
|
|||||||
|
|
||||||
open override func updateView(_ size: CGFloat) {
|
open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
|
|
||||||
var width = size
|
|
||||||
if MVMCoreGetterUtility.fequal(a: Float.leastNormalMagnitude, b: Float(size)) {
|
|
||||||
width = MVMCoreUIUtility.getWidth()
|
|
||||||
}
|
|
||||||
|
|
||||||
titleLabel?.font = MFStyler.fontB2(forWidth: width)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
contentMode = .redraw
|
contentMode = .redraw
|
||||||
setTitleColor(.mvmBlack, for: .normal)
|
setTitleColor(VDSColor.elementsPrimaryOnlight, for: .normal)
|
||||||
setTitleColor(.mvmCoolGray6, for: .disabled)
|
setTitleColor(VDSColor.interactiveDisabledOnlight, for: .disabled)
|
||||||
|
setTitleColor(VDSColor.interactiveActiveOnlight, for: .highlighted)
|
||||||
titleLabel?.numberOfLines = 1
|
titleLabel?.numberOfLines = 1
|
||||||
titleLabel?.lineBreakMode = .byTruncatingTail
|
titleLabel?.lineBreakMode = .byTruncatingTail
|
||||||
titleLabel?.textAlignment = .left
|
titleLabel?.textAlignment = .left
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import VDSColorTokens
|
||||||
|
|
||||||
open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol {
|
open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -22,11 +22,15 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
|||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
public var action: ActionModelProtocol
|
public var action: ActionModelProtocol
|
||||||
public var enabled = true
|
public var enabled = true
|
||||||
public var enabledColor = Color(uiColor: .mvmBlack)
|
public var enabledColor = Color(uiColor: VDSColor.elementsPrimaryOnlight)
|
||||||
public var enabledColor_inverted = Color(uiColor: .mvmWhite)
|
public var enabledColor_inverted = Color(uiColor: VDSColor.elementsPrimaryOndark)
|
||||||
public var disabledColor = Color(uiColor: .mvmCoolGray6)
|
public var disabledColor = Color(uiColor: VDSColor.interactiveDisabledOnlight)
|
||||||
public var disabledColor_inverted = Color(uiColor: .mvmCoolGray10)
|
public var disabledColor_inverted = Color(uiColor: VDSColor.interactiveDisabledOndark)
|
||||||
|
public var activeColor = Color(uiColor: VDSColor.interactiveActiveOnlight)
|
||||||
|
public var activeColor_inverted = Color(uiColor: VDSColor.interactiveActiveOndark)
|
||||||
|
|
||||||
public var inverted = false
|
public var inverted = false
|
||||||
|
public var size:linkFontSize = linkFontSize.small
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
@ -53,9 +57,30 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
|||||||
case enabledColor_inverted
|
case enabledColor_inverted
|
||||||
case disabledColor
|
case disabledColor
|
||||||
case disabledColor_inverted
|
case disabledColor_inverted
|
||||||
|
case activeColor
|
||||||
|
case activeColor_inverted
|
||||||
case inverted
|
case inverted
|
||||||
|
case size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum linkFontSize: String, Codable {
|
||||||
|
case small
|
||||||
|
case large
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Method
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
func getFont(_ type: linkFontSize) -> UIFont {
|
||||||
|
switch type {
|
||||||
|
case .small:
|
||||||
|
return MFStyler.fontRegularBodySmall()
|
||||||
|
case .large:
|
||||||
|
return MFStyler.fontRegularBodyLarge()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -92,6 +117,17 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
|||||||
if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) {
|
if let disabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor_inverted) {
|
||||||
self.disabledColor_inverted = disabledColor_inverted
|
self.disabledColor_inverted = disabledColor_inverted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let activeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor) {
|
||||||
|
self.activeColor = activeColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let activeColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor_inverted) {
|
||||||
|
self.activeColor_inverted = activeColor_inverted
|
||||||
|
}
|
||||||
|
if let size = try typeContainer.decodeIfPresent(linkFontSize.self, forKey: .size) {
|
||||||
|
self.size = size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -107,5 +143,8 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
|||||||
try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted)
|
try container.encode(enabledColor_inverted, forKey: .enabledColor_inverted)
|
||||||
try container.encode(disabledColor, forKey: .disabledColor)
|
try container.encode(disabledColor, forKey: .disabledColor)
|
||||||
try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted)
|
try container.encode(disabledColor_inverted, forKey: .disabledColor_inverted)
|
||||||
|
try container.encode(activeColor, forKey: .activeColor)
|
||||||
|
try container.encode(activeColor_inverted, forKey: .activeColor_inverted)
|
||||||
|
try container.encodeIfPresent(size, forKey: .size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import VDSColorTokens
|
||||||
|
|
||||||
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -23,21 +23,29 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
|
|
||||||
/// Need to re-style on set.
|
/// Need to re-style on set.
|
||||||
open override var isEnabled: Bool {
|
open override var isEnabled: Bool {
|
||||||
didSet { style() }
|
didSet { style(with: buttonModel) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open var buttonSize: Styler.Button.Size = .standard {
|
open var buttonSize: Styler.Button.Size = .standard {
|
||||||
didSet { buttonModel?.size = buttonSize }
|
didSet { buttonModel?.size = buttonSize }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Constraints
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public var widthConstraint: NSLayoutConstraint?
|
||||||
|
public var minimumWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public convenience init(asPrimaryButton isPrimary: Bool, makeTiny istiny: Bool) {
|
@objc public convenience init(asPrimaryButton isPrimary: Bool, makeTiny istiny: Bool) {
|
||||||
self.init()
|
let model = ButtonModel(with: "", action: ActionNoopModel())
|
||||||
buttonSize = istiny ? .tiny : .standard
|
model.style = isPrimary ? .primary : .secondary
|
||||||
isPrimary ? stylePrimary() : styleSecondary()
|
model.size = istiny ? .tiny : .standard
|
||||||
|
self.init(model: model, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -68,39 +76,26 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
|
|
||||||
/// 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() {
|
||||||
|
let buttonModel = ButtonModel(primaryButtonWith: "", action: ActionNoopModel())
|
||||||
enabledTitleColor = buttonModel?.enabledColors.text ?? .mvmWhite
|
style(with: buttonModel)
|
||||||
disabledTitleColor = buttonModel?.disabledColors.text ?? .mvmWhite
|
|
||||||
layer.borderWidth = 0
|
|
||||||
backgroundColor = isEnabled ? buttonModel?.enabledColors.fill ?? .mvmBlack : buttonModel?.disabledColors.fill ?? .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() {
|
||||||
|
let buttonModel = ButtonModel(secondaryButtonWith: "", action: ActionNoopModel())
|
||||||
enabledTitleColor = buttonModel?.enabledColors.text ?? .mvmBlack
|
style(with: buttonModel)
|
||||||
disabledTitleColor = buttonModel?.disabledColors.text ?? .mvmCoolGray6
|
|
||||||
backgroundColor = .clear
|
|
||||||
layer.borderWidth = 1
|
|
||||||
borderColor = isEnabled ? buttonModel?.enabledColors.border ?? .mvmBlack : buttonModel?.disabledColors.border ?? .mvmCoolGray6
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Styles the button based on the model style
|
/// Styles the button based on the model style
|
||||||
private func style() {
|
private func style(with model: ButtonModel?) {
|
||||||
|
|
||||||
switch buttonModel?.style {
|
layer.borderWidth = model?.style == .secondary ? 1 : 0
|
||||||
case .secondary:
|
|
||||||
styleSecondary()
|
|
||||||
|
|
||||||
default:
|
|
||||||
stylePrimary()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let titleColor = buttonModel?.enabledColors.text {
|
if let titleColor = model?.enabledColors.text {
|
||||||
enabledTitleColor = titleColor
|
enabledTitleColor = titleColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if let disabledTitleColor = buttonModel?.disabledColors.text {
|
if let disabledTitleColor = model?.disabledColors.text {
|
||||||
self.disabledTitleColor = disabledTitleColor
|
self.disabledTitleColor = disabledTitleColor
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,72 +105,46 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if isEnabled {
|
if isEnabled {
|
||||||
if let fillColor = buttonModel?.enabledColors.fill {
|
if let fillColor = model?.enabledColors.fill {
|
||||||
backgroundColor = fillColor
|
backgroundColor = fillColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if let borderColor = buttonModel?.enabledColors.border {
|
if let borderColor = model?.enabledColors.border {
|
||||||
layer.borderWidth = 1
|
|
||||||
self.borderColor = borderColor
|
self.borderColor = borderColor
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let fillColor = buttonModel?.disabledColors.fill {
|
if let fillColor = model?.disabledColors.fill {
|
||||||
backgroundColor = fillColor
|
backgroundColor = fillColor
|
||||||
}
|
}
|
||||||
|
|
||||||
if let borderColor = buttonModel?.disabledColors.border {
|
if let borderColor = model?.disabledColors.border {
|
||||||
layer.borderWidth = 1
|
|
||||||
self.borderColor = borderColor
|
self.borderColor = borderColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getInnerPadding() -> CGFloat {
|
private func getInnerPadding() -> CGFloat {
|
||||||
getHeight() / 2.0
|
buttonSize.getHeight() / 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getHeight() -> CGFloat {
|
|
||||||
PillButton.getHeight(for: buttonSize, size: size)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func getHeight(for buttonSize: Styler.Button.Size?, size: CGFloat) -> CGFloat {
|
|
||||||
|
|
||||||
|
private func getContentEdgeInsets() -> UIEdgeInsets {
|
||||||
|
var verticalPadding = 0.0
|
||||||
|
var horizontalPadding = 0.0
|
||||||
switch buttonSize {
|
switch buttonSize {
|
||||||
|
case .standard:
|
||||||
|
verticalPadding = Padding.Three
|
||||||
|
horizontalPadding = Padding.Five
|
||||||
|
break
|
||||||
|
case .small:
|
||||||
|
verticalPadding = Padding.Two
|
||||||
|
horizontalPadding = Padding.Four
|
||||||
|
break
|
||||||
case .tiny:
|
case .tiny:
|
||||||
let tinyHeight = Styler.Button.Size.tiny.getHeight()
|
verticalPadding = Padding.One
|
||||||
return MFSizeObject(standardSize: tinyHeight,
|
horizontalPadding = Padding.Two
|
||||||
standardiPadPortraitSize: 34,
|
break
|
||||||
iPadProLandscapeSize: 38)?.getValueBased(onSize: size) ?? tinyHeight
|
|
||||||
|
|
||||||
default:
|
|
||||||
let standardHeight = Styler.Button.Size.standard.getHeight()
|
|
||||||
return MFSizeObject(standardSize: standardHeight,
|
|
||||||
standardiPadPortraitSize: 46,
|
|
||||||
iPadProLandscapeSize: 50)?.getValueBased(onSize: size) ?? standardHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func getMinimumWidth() -> CGFloat {
|
|
||||||
|
|
||||||
switch buttonSize {
|
|
||||||
case .tiny:
|
|
||||||
return MFSizeObject(standardSize: 49,
|
|
||||||
standardiPadPortraitSize: 90,
|
|
||||||
iPadProLandscapeSize: 135)?.getValueBased(onSize: size) ?? 49
|
|
||||||
|
|
||||||
default: return 151
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open override var intrinsicContentSize: CGSize {
|
|
||||||
if buttonSize == .tiny {
|
|
||||||
let size = super.intrinsicContentSize
|
|
||||||
let width = size.width + (2 * getInnerPadding())
|
|
||||||
return CGSize(width: max(width, getMinimumWidth()), height: getHeight())
|
|
||||||
} else {
|
|
||||||
let width = Padding.Component.gutterForApplicationWidth + (2.0 * Padding.Component.columnFor(size: MVMCoreUISplitViewController.getApplicationViewWidth()))
|
|
||||||
return CGSize(width: min(292, width), height: getHeight())
|
|
||||||
}
|
}
|
||||||
|
return UIEdgeInsets(top: verticalPadding, left: horizontalPadding, bottom: verticalPadding, right: horizontalPadding)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -187,6 +156,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|
||||||
guard let model = model as? ButtonModel else { return }
|
guard let model = model as? ButtonModel else { return }
|
||||||
|
|
||||||
setTitle(model.title, for: .normal)
|
setTitle(model.title, for: .normal)
|
||||||
if let accessibilityText = model.accessibilityText {
|
if let accessibilityText = model.accessibilityText {
|
||||||
accessibilityLabel = accessibilityText
|
accessibilityLabel = accessibilityText
|
||||||
@ -206,24 +176,44 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||||
PillButton.getHeight(for: (model as? ButtonModel)?.size, size: MVMCoreUIUtility.getWidth())
|
return (model as? ButtonModel)?.size?.getHeight()
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
switch buttonSize {
|
switch buttonSize {
|
||||||
case .tiny:
|
case .tiny:
|
||||||
titleLabel?.font = MFFonts.mfFont75Bd(11 * (intrinsicContentSize.height / Styler.Button.Size.tiny.getHeight()))
|
titleLabel?.font = Styler.Font.BoldMicro.getFont(false)
|
||||||
|
case .small:
|
||||||
default:
|
titleLabel?.font = Styler.Font.BoldBodySmall.getFont(false)
|
||||||
titleLabel?.font = MFFonts.mfFont75Bd(13 * (intrinsicContentSize.height / Styler.Button.Size.standard.getHeight()))
|
case .standard:
|
||||||
|
titleLabel?.font = Styler.Font.BoldBodyLarge.getFont(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.cornerRadius = getInnerPadding()
|
layer.cornerRadius = getInnerPadding()
|
||||||
|
contentEdgeInsets = getContentEdgeInsets()
|
||||||
|
|
||||||
|
if let contraint = buttonModel?.width {
|
||||||
|
|
||||||
|
if widthConstraint == nil {
|
||||||
|
widthConstraint = widthAnchor.constraint(equalToConstant: contraint)
|
||||||
|
} else if widthConstraint?.constant != contraint {
|
||||||
|
widthConstraint?.constant = contraint
|
||||||
|
}
|
||||||
|
widthConstraint?.isActive = true
|
||||||
|
minimumWidthConstraint?.isActive = false
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if minimumWidthConstraint == nil {
|
||||||
|
minimumWidthConstraint = widthAnchor.constraint(greaterThanOrEqualToConstant: buttonSize.minimumWidth())
|
||||||
|
} else {
|
||||||
|
minimumWidthConstraint?.constant = buttonSize.minimumWidth()
|
||||||
|
}
|
||||||
|
minimumWidthConstraint?.isActive = true
|
||||||
|
widthConstraint?.isActive = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func setupView() {
|
open override func setupView() {
|
||||||
|
|||||||
@ -49,16 +49,19 @@ import UIKit
|
|||||||
public init() {
|
public init() {
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
model = LineModel(type: .secondary)
|
model = LineModel(type: .secondary)
|
||||||
|
setStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
model = LineModel(type: .secondary)
|
model = LineModel(type: .secondary)
|
||||||
|
setStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init?(coder: NSCoder) {
|
public required init?(coder: NSCoder) {
|
||||||
super.init(coder: coder)
|
super.init(coder: coder)
|
||||||
model = LineModel(type: .secondary)
|
model = LineModel(type: .secondary)
|
||||||
|
setStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
public required init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||||
|
|||||||
@ -58,11 +58,11 @@ import VDSColorTokens
|
|||||||
/// Sets the item colors.
|
/// Sets the item colors.
|
||||||
private func set(tabItemAppearance: UITabBarItemAppearance, model: TabBarModel) {
|
private func set(tabItemAppearance: UITabBarItemAppearance, model: TabBarModel) {
|
||||||
tabItemAppearance.normal.iconColor = model.unSelectedColor.uiColor
|
tabItemAppearance.normal.iconColor = model.unSelectedColor.uiColor
|
||||||
tabItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.unSelectedColor.uiColor, NSAttributedString.Key.font: MFFonts.mfFontTXRegular(10)]
|
tabItemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.unSelectedColor.uiColor, NSAttributedString.Key.font: MFFonts.mfFontTXBold(10)]
|
||||||
tabItemAppearance.normal.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
tabItemAppearance.normal.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
||||||
|
|
||||||
tabItemAppearance.selected.iconColor = model.selectedColor.uiColor
|
tabItemAppearance.selected.iconColor = model.selectedColor.uiColor
|
||||||
tabItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.selectedColor.uiColor, NSAttributedString.Key.font: MFFonts.mfFontTXRegular(10)]
|
tabItemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: model.selectedColor.uiColor, NSAttributedString.Key.font: MFFonts.mfFontTXBold(10)]
|
||||||
tabItemAppearance.selected.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
tabItemAppearance.selected.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,13 +50,17 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol {
|
|||||||
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.decodeMoleculeIfPresent(codingKey: .primaryButton)
|
|
||||||
if primaryButton?.style == nil {
|
//set context value for 'primary' style to be set for the primaryButton in case the
|
||||||
primaryButton?.style = .primary
|
//property is not returned in the JSON and once decoded, this value is removed from the context
|
||||||
|
try decoder.setContext(value: Styler.Button.Style.primary, for: "style") {
|
||||||
|
self.primaryButton = try typeContainer.decodeMoleculeIfPresent(codingKey: .primaryButton)
|
||||||
}
|
}
|
||||||
secondaryButton = try typeContainer.decodeMoleculeIfPresent(codingKey: .secondaryButton)
|
|
||||||
if secondaryButton?.style == nil {
|
//set context value for 'secondary' style to be set for the primaryButton in case the
|
||||||
secondaryButton?.style = .secondary
|
//property is not returned in the JSON and once decoded, this value is removed from the context
|
||||||
|
try decoder.setContext(value: Styler.Button.Style.secondary, for: "style") {
|
||||||
|
self.secondaryButton = try typeContainer.decodeMoleculeIfPresent(codingKey: .secondaryButton)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
|
|||||||
open var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
open var additionalLeftButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||||
open var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
open var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||||
open var titleView: MoleculeModelProtocol?
|
open var titleView: MoleculeModelProtocol?
|
||||||
open var titleOffset: UIOffset?
|
open var titleOffset: UIOffset? = UIOffset(horizontal: -CGFloat.greatestFiniteMagnitude, vertical: 0)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
@ -114,7 +114,9 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
|
|||||||
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
|
additionalRightButtons = try typeContainer.decodeModelsIfPresent(codingKey: .additionalRightButtons)
|
||||||
titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
|
titleView = try typeContainer.decodeModelIfPresent(codingKey: .titleView)
|
||||||
style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style)
|
style = try typeContainer.decodeIfPresent(NavigationItemStyle.self, forKey: .style)
|
||||||
titleOffset = try typeContainer.decodeIfPresent(UIOffset.self, forKey: .titleOffset) ?? UIOffset(horizontal: -CGFloat.greatestFiniteMagnitude, vertical: 0)
|
if let titleOffset = try typeContainer.decodeIfPresent(UIOffset.self, forKey: .titleOffset) {
|
||||||
|
self.titleOffset = titleOffset
|
||||||
|
}
|
||||||
line?.inverted = style == .dark
|
line?.inverted = style == .dark
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,4 +23,33 @@ public protocol MoleculeDelegateProtocol: AnyObject {
|
|||||||
extension MoleculeDelegateProtocol {
|
extension MoleculeDelegateProtocol {
|
||||||
|
|
||||||
public func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
public func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
||||||
|
|
||||||
|
public func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
|
||||||
|
let moduleJSON: [AnyHashable: Any]? = getModuleWithName(moleculeName)
|
||||||
|
guard let moduleJSON = moduleJSON as? [String: Any],
|
||||||
|
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
||||||
|
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
||||||
|
else { return nil }
|
||||||
|
|
||||||
|
do {
|
||||||
|
return try modelType.decode(jsonDict: moduleJSON as [String : Any]) as? MoleculeModelProtocol
|
||||||
|
} catch {
|
||||||
|
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MoleculeDelegateProtocol where Self: TemplateProtocol {
|
||||||
|
public func getRootMolecules() -> [MoleculeModelProtocol] {
|
||||||
|
templateModel?.rootMolecules ?? []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MoleculeDelegateProtocol where Self: MVMCoreViewControllerProtocol {
|
||||||
|
public func getModuleWithName(_ name: String?) -> [AnyHashable : Any]? {
|
||||||
|
guard let name = name else { return nil }
|
||||||
|
return loadObject??.modulesJSON?.optionalDictionaryForKey(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,43 +8,42 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol TemplateProtocol: AnyObject {
|
public protocol TemplateProtocol: AnyObject, PageProtocol {
|
||||||
associatedtype TemplateModel: TemplateModelProtocol
|
associatedtype TemplateModel: TemplateModelProtocol
|
||||||
var templateModel: TemplateModel? { get set }
|
var templateModel: TemplateModel? { get set }
|
||||||
|
|
||||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel
|
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension TemplateProtocol where Self: ViewController {
|
public extension TemplateProtocol {
|
||||||
|
|
||||||
|
// Utilize existing underlying property
|
||||||
|
var templateModel: TemplateModel? {
|
||||||
|
get {
|
||||||
|
pageModel as? TemplateModel
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
var mutableSelf = self
|
||||||
|
mutableSelf.pageModel = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to do common parsing logic.
|
||||||
func parseTemplate(json: [AnyHashable: Any]?) throws {
|
func parseTemplate(json: [AnyHashable: Any]?) throws {
|
||||||
guard let pageJSON = json else { return }
|
guard let pageJSON = json else { return }
|
||||||
|
let delegateObject = (self as? MVMCoreViewControllerProtocol)?.delegateObject?() as? MVMCoreUIDelegateObject
|
||||||
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
let data = try JSONSerialization.data(withJSONObject: pageJSON)
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder.create(with: delegateObject)
|
||||||
try decoder.add(delegateObject: delegateObjectIVar)
|
|
||||||
templateModel = try decodeTemplate(using: decoder, from: data)
|
templateModel = try decodeTemplate(using: decoder, from: data)
|
||||||
model = templateModel as? MVMControllerModelProtocol
|
|
||||||
guard let model = model else { return }
|
// Add additional required behaviors if applicable.
|
||||||
traverseAndAddRequiredBehaviors()
|
guard var behaviorHandlerModel = templateModel as? TemplateModelProtocol & PageBehaviorHandlerModelProtocol,
|
||||||
var behaviorHandler = self
|
var behaviorHandler = self as? PageBehaviorHandlerProtocol else { return }
|
||||||
behaviorHandler.createBehaviors(for: model, delegateObject: delegateObjectIVar)
|
behaviorHandlerModel.traverseAndAddRequiredBehaviors()
|
||||||
|
behaviorHandler.createBehaviors(for: behaviorHandlerModel, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel {
|
||||||
try decoder.decode(TemplateModel.self, from: data)
|
try decoder.decode(TemplateModel.self, from: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Traverses all models and adds any required behavior models.
|
|
||||||
func traverseAndAddRequiredBehaviors() {
|
|
||||||
guard var model = model else { return }
|
|
||||||
let behaviorModels: [PageBehaviorModelProtocol] = model.reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
|
|
||||||
if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer {
|
|
||||||
return accumulator + behaviorRequirer.getRequiredBehaviors()
|
|
||||||
}
|
|
||||||
return accumulator
|
|
||||||
}
|
|
||||||
for behavior in behaviorModels {
|
|
||||||
model.add(behavior: behavior)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// TemplateModel.swift
|
// BaseTemplateModel.swift
|
||||||
// MVMCoreUI
|
// MVMCoreUI
|
||||||
//
|
//
|
||||||
// Created by Scott Pfeil on 3/13/20.
|
// Created by Scott Pfeil on 3/13/20.
|
||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
@objcMembers open class BaseTemplateModel: MVMControllerModelProtocol, TabPageModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -13,7 +13,6 @@
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public typealias TemplateModel = CollectionTemplateModel
|
public typealias TemplateModel = CollectionTemplateModel
|
||||||
public var templateModel: CollectionTemplateModel?
|
|
||||||
|
|
||||||
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (CollectionItemModelProtocol & MoleculeModelProtocol))]?
|
public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (CollectionItemModelProtocol & MoleculeModelProtocol))]?
|
||||||
|
|
||||||
|
|||||||
@ -19,9 +19,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
|
|||||||
public var moleculesInfo: [MoleculeInfo]?
|
public var moleculesInfo: [MoleculeInfo]?
|
||||||
|
|
||||||
var observer: NSKeyValueObservation?
|
var observer: NSKeyValueObservation?
|
||||||
|
|
||||||
public var templateModel: ListPageTemplateModel?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -15,7 +15,6 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
var observer: NSKeyValueObservation?
|
var observer: NSKeyValueObservation?
|
||||||
public var templateModel: StackPageTemplateModel?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol {
|
@objcMembers open class ThreeLayerModelBase: BaseTemplateModel, ThreeLayerTemplateModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -9,11 +9,6 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers open class ThreeLayerTemplate<TemplateModel: ThreeLayerPageTemplateModel>: ThreeLayerViewController, TemplateProtocol {
|
@objcMembers open class ThreeLayerTemplate<TemplateModel: ThreeLayerPageTemplateModel>: ThreeLayerViewController, TemplateProtocol {
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Properties
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public var templateModel: TemplateModel?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
|||||||
@ -43,9 +43,6 @@ import UIKit
|
|||||||
|
|
||||||
public var selectedField: UIView?
|
public var selectedField: UIView?
|
||||||
|
|
||||||
// Stores the previous tab bar index.
|
|
||||||
public var tabBarIndex: Int?
|
|
||||||
|
|
||||||
/// Checks if the screen width has changed
|
/// Checks if the screen width has changed
|
||||||
open func screenSizeChanged() -> Bool {
|
open func screenSizeChanged() -> Bool {
|
||||||
!MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
!MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1)
|
||||||
@ -244,12 +241,6 @@ import UIKit
|
|||||||
view.backgroundColor = backgroundColor.uiColor
|
view.backgroundColor = backgroundColor.uiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update splitview properties
|
|
||||||
if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() {
|
|
||||||
MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0)
|
|
||||||
updateTabBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the manager of new data
|
// Notify the manager of new data
|
||||||
manager?.newDataReceived?(in: self)
|
manager?.newDataReceived?(in: self)
|
||||||
}
|
}
|
||||||
@ -267,34 +258,6 @@ import UIKit
|
|||||||
return model?.navigationBar
|
return model?.navigationBar
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - TabBar
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
open func updateTabBar() {
|
|
||||||
guard MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() == self else { return }
|
|
||||||
MVMCoreUISplitViewController.main()?.tabBar?.delegateObject = delegateObjectIVar
|
|
||||||
|
|
||||||
if let index = (model as? TabPageModelProtocol)?.tabBarIndex {
|
|
||||||
MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index)
|
|
||||||
} else if let index = loadObject?.requestParameters?.actionMap?["tabBarIndex"] as? Int {
|
|
||||||
MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index)
|
|
||||||
} else if let index = self.tabBarIndex {
|
|
||||||
MVMCoreUISplitViewController.main()?.tabBar?.highlightTab(at: index)
|
|
||||||
} else if let index = MVMCoreUISplitViewController.main()?.tabBar?.currentTabIndex() {
|
|
||||||
// Store current tab index for cases like back button.
|
|
||||||
self.tabBarIndex = index
|
|
||||||
}
|
|
||||||
|
|
||||||
if let hidden = (model as? TabPageModelProtocol)?.tabBarHidden {
|
|
||||||
MVMCoreUISplitViewController.main()?.updateTabBarShowing(!hidden)
|
|
||||||
} else if let hidden = loadObject?.requestParameters?.actionMap?["tabBarHidden"] as? Bool {
|
|
||||||
MVMCoreUISplitViewController.main()?.updateTabBarShowing(!hidden)
|
|
||||||
} else {
|
|
||||||
MVMCoreUISplitViewController.main()?.updateTabBarShowing(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - View Lifecycle
|
// MARK: - View Lifecycle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -349,12 +312,6 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
open func pageShown() {
|
open func pageShown() {
|
||||||
// Update split view properties if this is the current detail controller.
|
|
||||||
if self == MVMCoreUISplitViewController.main()?.getCurrentDetailViewController() {
|
|
||||||
MVMCoreUISplitViewController.main()?.setBottomProgressBarProgress(bottomProgress() ?? 0)
|
|
||||||
updateTabBar()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track.
|
// Track.
|
||||||
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
|
MVMCoreUISession.sharedGlobal()?.currentPageType = pageType
|
||||||
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
|
MVMCoreUILoggingHandler.shared()?.defaultLogPageState(forController: self)
|
||||||
@ -484,26 +441,6 @@ import UIKit
|
|||||||
model?.rootMolecules ?? []
|
model?.rootMolecules ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
open func getModuleWithName(_ name: String?) -> [AnyHashable: Any]? {
|
|
||||||
guard let name = name else { return nil }
|
|
||||||
return loadObject?.modulesJSON?.optionalDictionaryForKey(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
open func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? {
|
|
||||||
guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName),
|
|
||||||
let moleculeName = moduleJSON.optionalStringForKey("moleculeName"),
|
|
||||||
let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self)
|
|
||||||
else { return nil }
|
|
||||||
|
|
||||||
do {
|
|
||||||
return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol
|
|
||||||
} catch {
|
|
||||||
MVMCoreUILoggingHandler.logDebugMessage(withDelegate: "error: \(error)")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Needed otherwise when subclassed, the extension gets called.
|
// Needed otherwise when subclassed, the extension gets called.
|
||||||
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
||||||
|
|
||||||
@ -618,12 +555,4 @@ import UIKit
|
|||||||
selectedField = nil
|
selectedField = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Behavior Execution
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public func executeBehaviors<T>(_ behaviorBlock: (_ behavior: T) -> Void) {
|
|
||||||
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ public class AddRemoveMoleculesBehavior: PageCustomActionHandlerBehavior, PageMo
|
|||||||
self.delegate = delegateObject
|
self.delegate = delegateObject
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject) {
|
public func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
guard let list = delegate?.moleculeListDelegate else { return }
|
guard let list = delegate?.moleculeListDelegate else { return }
|
||||||
for case let model as (MoleculeModelProtocol & ListItemModelProtocol & AddMolecules) in rootMolecules {
|
for case let model as (MoleculeModelProtocol & ListItemModelProtocol & AddMolecules) in rootMolecules {
|
||||||
if let moleculesToAdd = model.getRecursiveMoleculesToAdd(),
|
if let moleculesToAdd = model.getRecursiveMoleculesToAdd(),
|
||||||
|
|||||||
@ -23,3 +23,19 @@ public extension PageBehaviorHandlerModelProtocol {
|
|||||||
self.behaviors = newBehaviors
|
self.behaviors = newBehaviors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension PageBehaviorHandlerModelProtocol where Self: MoleculeTreeTraversalProtocol {
|
||||||
|
|
||||||
|
/// Traverses all models and adds any required behavior models.
|
||||||
|
mutating func traverseAndAddRequiredBehaviors() {
|
||||||
|
let behaviorModels: [PageBehaviorModelProtocol] = reduceDepthFirstTraverse(options: .childFirst, depth: 0, initialResult: []) { (accumulator, molecule, depth) in
|
||||||
|
if let behaviorRequirer = molecule as? PageBehaviorProtocolRequirer {
|
||||||
|
return accumulator + behaviorRequirer.getRequiredBehaviors()
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
for behavior in behaviorModels {
|
||||||
|
add(behavior: behavior)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -34,4 +34,9 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
}
|
}
|
||||||
self.behaviors = behaviors.count > 0 ? behaviors : nil
|
self.behaviors = behaviors.count > 0 ? behaviors : nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Executes all behaviors of type.
|
||||||
|
func executeBehaviors<T>(_ behaviorBlock: (_ behavior: T) -> Void) {
|
||||||
|
behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ public protocol PageBehaviorProtocol: ModelHandlerProtocol {
|
|||||||
|
|
||||||
public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
|
public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol {
|
||||||
|
|
||||||
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject)
|
func onPageNew(rootMolecules: [MoleculeModelProtocol], _ delegateObject: MVMCoreUIDelegateObject?)
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||||
@ -50,8 +50,11 @@ public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension MVMCoreUIDelegateObject {
|
public extension MVMCoreUIDelegateObject {
|
||||||
|
var behaviorModelDelegate: PageBehaviorHandlerModelProtocol? {
|
||||||
|
(moleculeDelegate as? PageProtocol)?.pageModel as? PageBehaviorHandlerModelProtocol
|
||||||
|
}
|
||||||
|
|
||||||
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
|
weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? {
|
||||||
(moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
|
moleculeDelegate as? (PageBehaviorHandlerProtocol & NSObjectProtocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public extension UINavigationController {
|
|||||||
/// Convenience function for setting the navigation bar ui
|
/// Convenience function for setting the navigation bar ui
|
||||||
func setNavigationBarUI(with model: NavigationItemModelProtocol) {
|
func setNavigationBarUI(with model: NavigationItemModelProtocol) {
|
||||||
let navigationBar = navigationBar
|
let navigationBar = navigationBar
|
||||||
let font = MFStyler.fontBoldBodySmall(false)
|
let font = MFStyler.fontBoldBodyLarge(false)
|
||||||
let backgroundColor = model.backgroundColor?.uiColor
|
let backgroundColor = model.backgroundColor?.uiColor
|
||||||
let tint = model.tintColor.uiColor
|
let tint = model.tintColor.uiColor
|
||||||
navigationBar.tintColor = tint
|
navigationBar.tintColor = tint
|
||||||
|
|||||||
@ -12,6 +12,64 @@ import UIKit
|
|||||||
// Navigation bar update functions
|
// Navigation bar update functions
|
||||||
public extension MVMCoreUISplitViewController {
|
public extension MVMCoreUISplitViewController {
|
||||||
|
|
||||||
|
/// Updates the state for various controls (navigation, tab, progress) for the controller.
|
||||||
|
func updateState(with viewController: UIViewController) {
|
||||||
|
guard let navigationController = navigationController,
|
||||||
|
navigationController.isDisplayed(viewController: viewController) else { return }
|
||||||
|
updateNavigationBarFor(viewController: viewController)
|
||||||
|
updateProgressBar(for: viewController)
|
||||||
|
updateTabBar(for: viewController)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Progress Bar
|
||||||
|
/// Updates the progress bar based on the page json for the view controller.
|
||||||
|
func updateProgressBar(for viewController: UIViewController) {
|
||||||
|
guard let viewController = viewController as? MVMCoreViewControllerProtocol else { return }
|
||||||
|
var progress: Float = 0.0
|
||||||
|
if let progressString = viewController.loadObject??.pageJSON?.optionalStringForKey(KeyProgressPercent),
|
||||||
|
let floatValue = Float(progressString) {
|
||||||
|
progress = floatValue/100
|
||||||
|
}
|
||||||
|
setBottomProgressBarProgress(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Tab Bar
|
||||||
|
/// Updates the tab bar based on the page json for the view controller.
|
||||||
|
func updateTabBar(for viewController: UIViewController) {
|
||||||
|
let mvmViewController = viewController as? MVMCoreViewControllerProtocol
|
||||||
|
tabBar?.delegateObject = mvmViewController?.delegateObject?() as? MVMCoreUIDelegateObject
|
||||||
|
|
||||||
|
let navigationIndex = (MVMCoreNavigationHandler.shared()?.getViewControllers(for: navigationController)?.count ?? 1) - 1
|
||||||
|
|
||||||
|
// Set the highlighted index. In terms of priority, Page > Action > Previous.
|
||||||
|
if let index = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarIndex {
|
||||||
|
tabBar?.highlightTab(at: index)
|
||||||
|
} else if let index = mvmViewController?.loadObject??.requestParameters?.actionMap?["tabBarIndex"] as? Int {
|
||||||
|
tabBar?.highlightTab(at: index)
|
||||||
|
} else if navigationIndex < tabBarIndices.count {
|
||||||
|
let index = (tabBarIndices[navigationIndex] as! NSNumber).intValue
|
||||||
|
tabBar?.highlightTab(at: index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store current tab index, so we can switch back when going back in hierarchy.
|
||||||
|
if tabBarIndices.count > 0 {
|
||||||
|
tabBarIndices.removeObjects(in: NSRange(location: navigationIndex, length: tabBarIndices.count - navigationIndex))
|
||||||
|
}
|
||||||
|
if let currentIndex = tabBar?.currentTabIndex() {
|
||||||
|
tabBarIndices.add(NSNumber(integerLiteral: currentIndex))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show/Hide. In terms of priority, Page > Action > Always Show.
|
||||||
|
if let hidden = ((viewController as? PageProtocol)?.pageModel as? TabPageModelProtocol)?.tabBarHidden {
|
||||||
|
updateTabBarShowing(!hidden)
|
||||||
|
} else if let hidden = mvmViewController?.loadObject??.requestParameters?.actionMap?["tabBarHidden"] as? Bool {
|
||||||
|
updateTabBarShowing(!hidden)
|
||||||
|
} else {
|
||||||
|
updateTabBarShowing(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Navigation Bar
|
||||||
/// Convenience function. Sets the navigation and split view properties for the view controller. Panel access is determined if view controller is a detail view protocol.
|
/// Convenience function. Sets the navigation and split view properties for the view controller. Panel access is determined if view controller is a detail view protocol.
|
||||||
func setNavigationBar(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) {
|
func setNavigationBar(for viewController: UIViewController, navigationController: UINavigationController, navigationItemModel: NavigationItemModelProtocol) {
|
||||||
guard navigationController == self.navigationController,
|
guard navigationController == self.navigationController,
|
||||||
@ -122,6 +180,7 @@ public extension MVMCoreUISplitViewController {
|
|||||||
setStatusBarForCurrentViewController()
|
setStatusBarForCurrentViewController()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Status Bar
|
||||||
/// Returns the bar style for the background color. Light if on a dark background, otherwise default.
|
/// Returns the bar style for the background color. Light if on a dark background, otherwise default.
|
||||||
func getStatusBarStyle(for backgroundColor: UIColor?) -> UIStatusBarStyle {
|
func getStatusBarStyle(for backgroundColor: UIColor?) -> UIStatusBarStyle {
|
||||||
var greyScale: CGFloat = 0
|
var greyScale: CGFloat = 0
|
||||||
@ -155,10 +214,10 @@ extension MVMCoreUISplitViewController: MVMCoreViewManagerProtocol {
|
|||||||
|
|
||||||
public func willDisplay(_ viewController: UIViewController) {
|
public func willDisplay(_ viewController: UIViewController) {
|
||||||
setupPanels()
|
setupPanels()
|
||||||
updateNavigationBarFor(viewController: viewController)
|
updateState(with: viewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func newDataReceived(in viewController: UIViewController) {
|
public func newDataReceived(in viewController: UIViewController) {
|
||||||
updateNavigationBarFor(viewController: viewController)
|
updateState(with: viewController)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,9 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
|||||||
/// Reference to the tabbar.
|
/// Reference to the tabbar.
|
||||||
@property (nullable, weak, nonatomic) UIView <TabBarProtocol>*tabBar;
|
@property (nullable, weak, nonatomic) UIView <TabBarProtocol>*tabBar;
|
||||||
|
|
||||||
|
/// Tab bar index history.
|
||||||
|
@property (nonnull, strong, nonatomic) NSMutableArray <NSNumber *>*tabBarIndices;
|
||||||
|
|
||||||
// Convenience getter
|
// Convenience getter
|
||||||
+ (nullable instancetype)mainSplitViewController;
|
+ (nullable instancetype)mainSplitViewController;
|
||||||
|
|
||||||
|
|||||||
@ -93,13 +93,20 @@ CGFloat const PanelAnimationDuration = 0.2;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (nullable instancetype)initWithLeftPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel {
|
- (nullable instancetype)initWithLeftPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)leftPanel rightPanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)rightPanel {
|
||||||
if (self = [super init]) {
|
if (self = [self init]) {
|
||||||
self.globalLeftPanel = leftPanel;
|
self.globalLeftPanel = leftPanel;
|
||||||
self.globalRightPanel = rightPanel;
|
self.globalRightPanel = rightPanel;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (nullable instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
self.tabBarIndices = [NSMutableArray array];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Main Subclassables
|
#pragma mark - Main Subclassables
|
||||||
|
|
||||||
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(NSNumber *)forWidth {
|
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(NSNumber *)forWidth {
|
||||||
|
|||||||
@ -19,7 +19,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
|
|||||||
|
|
||||||
/// Used to layout the ui.
|
/// Used to layout the ui.
|
||||||
public lazy var stackView: UIStackView = {
|
public lazy var stackView: UIStackView = {
|
||||||
let stackView = UIStackView(arrangedSubviews: [tabs, line, subNavigationController.view])
|
let stackView = UIStackView(arrangedSubviews: [tabs, subNavigationController.view])
|
||||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
stackView.isAccessibilityElement = false
|
stackView.isAccessibilityElement = false
|
||||||
stackView.axis = .vertical
|
stackView.axis = .vertical
|
||||||
@ -33,10 +33,6 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol,
|
|||||||
return tabs
|
return tabs
|
||||||
}()
|
}()
|
||||||
|
|
||||||
public lazy var line: Line = {
|
|
||||||
return Line(model: LineModel(type: .secondary), delegateObjectIVar, nil)
|
|
||||||
}()
|
|
||||||
|
|
||||||
public lazy var subNavigationController: UINavigationController = {
|
public lazy var subNavigationController: UINavigationController = {
|
||||||
let subNavigationController = SubNavManagerNavigationController(rootViewController: viewController)
|
let subNavigationController = SubNavManagerNavigationController(rootViewController: viewController)
|
||||||
subNavigationController.view.translatesAutoresizingMaskIntoConstraints = false
|
subNavigationController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|||||||
@ -125,8 +125,6 @@
|
|||||||
|
|
||||||
- (void)openURLInSafariWebView:(nonnull NSURL *)url {
|
- (void)openURLInSafariWebView:(nonnull NSURL *)url {
|
||||||
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:url];
|
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:url];
|
||||||
safariViewController.preferredBarTintColor = [UIColor whiteColor];
|
|
||||||
safariViewController.preferredControlTintColor = [UIColor blackColor];
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:safariViewController animated:YES];
|
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:safariViewController animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -178,20 +178,33 @@ open class Styler {
|
|||||||
case primary
|
case primary
|
||||||
case secondary
|
case secondary
|
||||||
}
|
}
|
||||||
|
///MVA 3.0 - Button sizes are standard(default size), small, Tiny. Tiny button has been depricated as of Rebranding 3.0.
|
||||||
public enum Size: String, Codable {
|
public enum Size: String, Codable {
|
||||||
case standard
|
case standard
|
||||||
|
case small
|
||||||
case tiny
|
case tiny
|
||||||
|
|
||||||
func getHeight() -> CGFloat {
|
func getHeight() -> CGFloat {
|
||||||
switch self {
|
switch self {
|
||||||
case .standard:
|
case .standard:
|
||||||
return 42
|
return 44
|
||||||
|
case .small:
|
||||||
|
return 32
|
||||||
case .tiny:
|
case .tiny:
|
||||||
return 20
|
return 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func minimumWidth() -> CGFloat {
|
||||||
|
switch self {
|
||||||
|
case .standard:
|
||||||
|
return 76
|
||||||
|
case .small:
|
||||||
|
return 0
|
||||||
|
case .tiny:
|
||||||
|
return 49
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -204,7 +204,6 @@
|
|||||||
|
|
||||||
// Sets up to use a button action. Always uses the top view controller
|
// Sets up to use a button action. Always uses the top view controller
|
||||||
PillButton *button = [[PillButton alloc] initAsPrimaryButton:false makeTiny:true];
|
PillButton *button = [[PillButton alloc] initAsPrimaryButton:false makeTiny:true];
|
||||||
[button styleSecondary];
|
|
||||||
[button setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
|
[button setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];
|
||||||
[button setContentHuggingPriority:800 forAxis:UILayoutConstraintAxisHorizontal];
|
[button setContentHuggingPriority:800 forAxis:UILayoutConstraintAxisHorizontal];
|
||||||
|
|
||||||
|
|||||||
@ -69,10 +69,7 @@ open class TopNotificationModel: Codable {
|
|||||||
/// Decodes the top alert json to a model.
|
/// Decodes the top alert json to a model.
|
||||||
public static func decode(json: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?) throws -> Self {
|
public static func decode(json: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?) throws -> Self {
|
||||||
let data = try JSONSerialization.data(withJSONObject: json)
|
let data = try JSONSerialization.data(withJSONObject: json)
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder.create(with: delegateObject)
|
||||||
if let delegateObject = delegateObject {
|
|
||||||
try decoder.add(delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
return try decoder.decode(self, from: data)
|
return try decoder.decode(self, from: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user