merge
This commit is contained in:
commit
2d05cbe3a8
@ -105,6 +105,7 @@
|
||||
0A9D09212433796500D2E6C0 /* CarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D091B2433796500D2E6C0 /* CarouselIndicatorModel.swift */; };
|
||||
0A9D09222433796500D2E6C0 /* CarouselIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D091C2433796500D2E6C0 /* CarouselIndicator.swift */; };
|
||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
||||
0AA4D2E125CAEC72008DB32D /* AccessibilityModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA4D2E025CAEC72008DB32D /* AccessibilityModelProtocol.swift */; };
|
||||
0AB000BA24BF63490090C5E7 /* ModalListPageTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB000B924BF63490090C5E7 /* ModalListPageTemplateModel.swift */; };
|
||||
0AB000BC24BF64A50090C5E7 /* ModalStackPageTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB000BB24BF64A50090C5E7 /* ModalStackPageTemplateModel.swift */; };
|
||||
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; };
|
||||
@ -656,6 +657,7 @@
|
||||
0A9D091C2433796500D2E6C0 /* CarouselIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarouselIndicator.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>"; };
|
||||
0AA4D2E025CAEC72008DB32D /* AccessibilityModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityModelProtocol.swift; sourceTree = "<group>"; };
|
||||
0AB000B924BF63490090C5E7 /* ModalListPageTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalListPageTemplateModel.swift; sourceTree = "<group>"; };
|
||||
0AB000BB24BF64A50090C5E7 /* ModalStackPageTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalStackPageTemplateModel.swift; sourceTree = "<group>"; };
|
||||
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = "<group>"; };
|
||||
@ -1121,6 +1123,7 @@
|
||||
011B58EE23A2AA850085F53C /* ModelProtocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0AA4D2E025CAEC72008DB32D /* AccessibilityModelProtocol.swift */,
|
||||
D2E2A9A023E095AB000B42E6 /* ButtonModelProtocol.swift */,
|
||||
014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */,
|
||||
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
|
||||
@ -1724,6 +1727,8 @@
|
||||
D2092348244A51D40044AD09 /* RadioSwatchModel.swift */,
|
||||
AAB9C109243496DD00151545 /* RadioSwatch.swift */,
|
||||
AA85236B244435A20059CC1E /* RadioSwatchCollectionViewCell.swift */,
|
||||
D260105223CEA61600764D80 /* ToggleModel.swift */,
|
||||
0AA33B392398524F0067DD0F /* Toggle.swift */,
|
||||
AAA7CD68250641F90045B959 /* HeartModel.swift */,
|
||||
AAA7CD6A250642080045B959 /* Heart.swift */,
|
||||
);
|
||||
@ -2021,8 +2026,6 @@
|
||||
D28A838223CCBD3F00DFE4FC /* WheelModel.swift */,
|
||||
943784F3236B77BB006A1E82 /* Wheel.swift */,
|
||||
943784F4236B77BB006A1E82 /* WheelAnimationHandler.swift */,
|
||||
D260105223CEA61600764D80 /* ToggleModel.swift */,
|
||||
0AA33B392398524F0067DD0F /* Toggle.swift */,
|
||||
0AE98BB623FF18E9004C5109 /* ArrowModel.swift */,
|
||||
0AE98BB423FF18D2004C5109 /* Arrow.swift */,
|
||||
94382085243238D100B43AF3 /* WebViewModel.swift */,
|
||||
@ -2045,10 +2048,10 @@
|
||||
D29DF22B21E6A0FA003B2FB9 /* TextFields */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */,
|
||||
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */,
|
||||
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */,
|
||||
0A21DB7E235DECC500C160A2 /* EntryField.swift */,
|
||||
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */,
|
||||
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */,
|
||||
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */,
|
||||
0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */,
|
||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */,
|
||||
@ -2175,6 +2178,7 @@
|
||||
D2B18B7D236090D500A9AEDC /* BaseClasses */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||
0A6682B3243769C700AD3CA1 /* TextView.swift */,
|
||||
C003506023AA94CD00B6AC29 /* Button.swift */,
|
||||
D2B18B7E2360913400A9AEDC /* Control.swift */,
|
||||
@ -2185,7 +2189,6 @@
|
||||
BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */,
|
||||
D21B7F70243BAC1600051ABF /* CollectionViewCell.swift */,
|
||||
D264FAA92440F97600D98315 /* CollectionView.swift */,
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||
0A7918F423F5E7EA00772FF4 /* ImageView.swift */,
|
||||
D272F5F82473163100BD1A8F /* BarButtonItem.swift */,
|
||||
D2EC7BDC2527B83700F540AF /* SectionHeaderFooterView.swift */,
|
||||
@ -2865,6 +2868,7 @@
|
||||
012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */,
|
||||
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */,
|
||||
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */,
|
||||
0AA4D2E125CAEC72008DB32D /* AccessibilityModelProtocol.swift in Sources */,
|
||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
||||
D29C559025C095210082E7D6 /* Video.swift in Sources */,
|
||||
@ -2985,6 +2989,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@ -3050,6 +3055,7 @@
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
||||
@ -18,6 +18,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
|
||||
|
||||
public static var identifier: String = "button"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
public var enabled: Bool = true
|
||||
@ -93,27 +94,27 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
|
||||
//--------------------------------------------------
|
||||
|
||||
public func enabled_fillColor() -> UIColor? {
|
||||
return (inverted ? enabledFillColor_inverted : enabledFillColor)?.uiColor
|
||||
(inverted ? enabledFillColor_inverted : enabledFillColor)?.uiColor
|
||||
}
|
||||
|
||||
public func enabled_textColor() -> UIColor? {
|
||||
return (inverted ? enabledTextColor_inverted : enabledTextColor)?.uiColor
|
||||
(inverted ? enabledTextColor_inverted : enabledTextColor)?.uiColor
|
||||
}
|
||||
|
||||
public func enabled_borderColor() -> UIColor? {
|
||||
return (inverted ? enabledBorderColor_inverted : enabledBorderColor)?.uiColor
|
||||
(inverted ? enabledBorderColor_inverted : enabledBorderColor)?.uiColor
|
||||
}
|
||||
|
||||
public func disabled_fillColor() -> UIColor? {
|
||||
return (inverted ? disabledFillColor_inverted : disabledFillColor)?.uiColor
|
||||
(inverted ? disabledFillColor_inverted : disabledFillColor)?.uiColor
|
||||
}
|
||||
|
||||
public func disabled_textColor() -> UIColor? {
|
||||
return (inverted ? disabledTextColor_inverted : disabledTextColor)?.uiColor
|
||||
(inverted ? disabledTextColor_inverted : disabledTextColor)?.uiColor
|
||||
}
|
||||
|
||||
public func disabled_borderColor() -> UIColor? {
|
||||
return (inverted ? disabledBorderColor_inverted : disabledBorderColor)?.uiColor
|
||||
(inverted ? disabledBorderColor_inverted : disabledBorderColor)?.uiColor
|
||||
}
|
||||
|
||||
/// Defines the default appearance for the primary style.
|
||||
@ -172,6 +173,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case title
|
||||
case inverted
|
||||
case action
|
||||
@ -195,6 +197,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
|
||||
@ -252,6 +255,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupW
|
||||
try container.encode(inverted, forKey: .inverted)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeIfPresent(enabledFillColor, forKey: .fillColor)
|
||||
try container.encodeIfPresent(enabledTextColor, forKey: .textColor)
|
||||
try container.encodeIfPresent(enabledBorderColor, forKey: .borderColor)
|
||||
|
||||
@ -127,7 +127,6 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
}
|
||||
|
||||
public func updateCaretSpacing(_ spacing: CGFloat) {
|
||||
|
||||
caretSpacingConstraint?.constant = spacing
|
||||
}
|
||||
|
||||
@ -151,15 +150,9 @@ open class CaretLink: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
setTitle(model.title, for: .normal)
|
||||
}
|
||||
|
||||
public func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
public func needsToBeConstrained() -> Bool { true }
|
||||
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .leading
|
||||
}
|
||||
open func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 10.5
|
||||
}
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 10.5 }
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea
|
||||
|
||||
public static var identifier: String = "caretLink"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
public var enabledColor: Color = Color(uiColor: .mvmBlack)
|
||||
@ -41,6 +42,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case title
|
||||
case action
|
||||
case enabledColor_inverted
|
||||
@ -60,6 +62,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
|
||||
if let enabledColor_inverted = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledColor_inverted) {
|
||||
@ -94,6 +97,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encode(enabled, forKey: .enabledColor)
|
||||
try container.encodeIfPresent(disabledColor, forKey: .disabledColor)
|
||||
|
||||
@ -11,18 +11,18 @@ import UIKit
|
||||
|
||||
@objcMembers open class Link: Button {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
// MARK: - Draw
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func draw(_ rect: CGRect) {
|
||||
|
||||
guard let textRect = titleLabel?.frame else { return }
|
||||
|
||||
let context = UIGraphicsGetCurrentContext()
|
||||
guard let textRect = titleLabel?.frame,
|
||||
let context = UIGraphicsGetCurrentContext()
|
||||
else { return }
|
||||
|
||||
// Set line to the same color as the text
|
||||
if let color = titleLabel?.textColor?.cgColor {
|
||||
context?.setStrokeColor(color)
|
||||
context.setStrokeColor(color)
|
||||
}
|
||||
|
||||
// x should be according to the text, not the button
|
||||
@ -31,9 +31,9 @@ import UIKit
|
||||
// Line is 1 point below the text
|
||||
let y = textRect.origin.y + textRect.size.height + 1
|
||||
|
||||
context?.move(to: CGPoint(x: x, y: y))
|
||||
context?.addLine(to: CGPoint(x: x + textRect.size.width, y: y))
|
||||
context?.strokePath()
|
||||
context.move(to: CGPoint(x: x, y: y))
|
||||
context.addLine(to: CGPoint(x: x + textRect.size.width, y: y))
|
||||
context.strokePath()
|
||||
}
|
||||
|
||||
open override var intrinsicContentSize: CGSize {
|
||||
@ -58,9 +58,7 @@ import UIKit
|
||||
set(with: model.action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 31
|
||||
}
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 31 }
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
@ -69,16 +67,12 @@ extension Link {
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
var width = size
|
||||
if MVMCoreGetterUtility.fequal(a: Float.leastNormalMagnitude, b: Float(size)) {
|
||||
width = MVMCoreUIUtility.getWidth()
|
||||
}
|
||||
|
||||
self.titleLabel?.font = MFStyler.fontB2(forWidth: width)
|
||||
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() {
|
||||
@ -98,7 +92,5 @@ extension Link {
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
extension Link: MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .leading
|
||||
}
|
||||
open func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||
}
|
||||
|
||||
@ -14,11 +14,10 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public class var identifier: String {
|
||||
return "link"
|
||||
}
|
||||
public class var identifier: String { "link" }
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
public var enabled = true
|
||||
@ -44,6 +43,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case title
|
||||
case action
|
||||
case enabled
|
||||
@ -62,6 +62,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
|
||||
@ -95,6 +96,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encode(inverted, forKey: .inverted)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
|
||||
@ -18,7 +18,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
var size = MVMCoreUIUtility.getWidth()
|
||||
|
||||
var buttonModel: ButtonModel? {
|
||||
get { return model as? ButtonModel }
|
||||
get { model as? ButtonModel }
|
||||
}
|
||||
|
||||
/// Need to re-style on set.
|
||||
@ -27,9 +27,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
}
|
||||
|
||||
open var buttonSize: Styler.Button.Size = .standard {
|
||||
didSet {
|
||||
buttonModel?.size = buttonSize
|
||||
}
|
||||
didSet { buttonModel?.size = buttonSize }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -47,12 +45,12 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
//--------------------------------------------------
|
||||
|
||||
public var enabledTitleColor: UIColor? {
|
||||
get { return titleColor(for: .normal) }
|
||||
get { titleColor(for: .normal) }
|
||||
set { setTitleColor(newValue, for: .normal) }
|
||||
}
|
||||
|
||||
public var disabledTitleColor: UIColor? {
|
||||
get { return titleColor(for: .disabled) }
|
||||
get { titleColor(for: .disabled) }
|
||||
set { setTitleColor(newValue, for: .disabled) }
|
||||
}
|
||||
|
||||
@ -106,6 +104,11 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
self.disabledTitleColor = disabledTitleColor
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// Useful to detect with isHittable when performing UI testing.
|
||||
isAccessibilityElement = isEnabled
|
||||
#endif
|
||||
|
||||
if isEnabled {
|
||||
if let fillColor = buttonModel?.enabledColors.fill {
|
||||
backgroundColor = fillColor
|
||||
@ -128,7 +131,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
}
|
||||
|
||||
private func getInnerPadding() -> CGFloat {
|
||||
return getHeight() / 2.0
|
||||
getHeight() / 2.0
|
||||
}
|
||||
|
||||
private func getHeight() -> CGFloat {
|
||||
@ -181,9 +184,11 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
guard let model = model as? ButtonModel else { return }
|
||||
setTitle(model.title, for: .normal)
|
||||
|
||||
if let size = model.size {
|
||||
buttonSize = size
|
||||
}
|
||||
|
||||
model.updateUI = { [weak self] in
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||
self?.enableField(model.enabled)
|
||||
@ -228,9 +233,7 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol {
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .center
|
||||
}
|
||||
open func horizontalAlignment() -> UIStackView.Alignment { .center }
|
||||
|
||||
public func enableField(_ enable: Bool) {
|
||||
isEnabled = enable
|
||||
|
||||
@ -14,9 +14,7 @@
|
||||
public var caretView: CaretViewModel?
|
||||
public var action: ActionModelProtocol?
|
||||
|
||||
public override class var identifier: String {
|
||||
return ""
|
||||
}
|
||||
public override class var identifier: String { "" }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
|
||||
@ -23,15 +23,15 @@ import UIKit
|
||||
}()
|
||||
|
||||
public var dateFormat: String? {
|
||||
get { dateDropdownModel?.dateFormat }
|
||||
set {
|
||||
guard let newValue = newValue else { return }
|
||||
dateDropdownModel?.dateFormat = newValue
|
||||
}
|
||||
get { return dateDropdownModel?.dateFormat }
|
||||
}
|
||||
|
||||
public var dateDropdownModel: DateDropdownEntryFieldModel? {
|
||||
return model as? DateDropdownEntryFieldModel
|
||||
model as? DateDropdownEntryFieldModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -11,9 +11,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "dateDropdownEntryField"
|
||||
}
|
||||
public override class var identifier: String { "dateDropdownEntryField" }
|
||||
|
||||
public var dateFormatter: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
|
||||
@ -43,7 +43,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public override var showError: Bool {
|
||||
get { return super.showError }
|
||||
get { super.showError }
|
||||
set (error) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
@ -357,9 +357,7 @@ import UIKit
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 115
|
||||
}
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 115 }
|
||||
}
|
||||
|
||||
// MARK: - TextField Delegate
|
||||
|
||||
@ -12,9 +12,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "digitTextField"
|
||||
}
|
||||
public override class var identifier: String { "digitTextField" }
|
||||
|
||||
public var digits: Int = 4
|
||||
|
||||
|
||||
@ -345,9 +345,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 115
|
||||
}
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 115 }
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
|
||||
@ -14,9 +14,7 @@ import Foundation
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public class var identifier: String {
|
||||
return ""
|
||||
}
|
||||
public class var identifier: String { "" }
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
|
||||
@ -120,12 +120,10 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
// MARK:- Base Picker Delegate
|
||||
extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
||||
|
||||
@objc public func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
return 1
|
||||
}
|
||||
@objc public func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
|
||||
|
||||
@objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
return pickerData.count
|
||||
pickerData.count
|
||||
}
|
||||
|
||||
@objc public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
||||
|
||||
@ -11,9 +11,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "dropDown"
|
||||
}
|
||||
public override class var identifier: String { "dropDown" }
|
||||
|
||||
public var options: [String] = []
|
||||
public var selectedIndex: Int?
|
||||
|
||||
@ -211,17 +211,14 @@ import MVMCore
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,5 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "mdnEntryField"
|
||||
}
|
||||
public override class var identifier: String { "mdnEntryField" }
|
||||
}
|
||||
|
||||
@ -54,9 +54,7 @@ import UIKit
|
||||
/// Validate when user resigns editing. Default: true
|
||||
public var validateWhenDoneEditing: Bool = true
|
||||
|
||||
public var textEntryFieldModel: TextEntryFieldModel? {
|
||||
return model as? TextEntryFieldModel
|
||||
}
|
||||
public var textEntryFieldModel: TextEntryFieldModel? { model as? TextEntryFieldModel }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
@ -96,7 +94,7 @@ import UIKit
|
||||
|
||||
/// The text of this TextField.
|
||||
open override var text: String? {
|
||||
get { return textField.text }
|
||||
get { textField.text }
|
||||
set {
|
||||
textField.text = newValue
|
||||
textEntryFieldModel?.text = newValue
|
||||
@ -105,7 +103,7 @@ import UIKit
|
||||
|
||||
/// Placeholder access for the TextField.
|
||||
public var placeholder: String? {
|
||||
get { return textField.placeholder }
|
||||
get { textField.placeholder }
|
||||
set { textField.placeholder = newValue }
|
||||
}
|
||||
|
||||
@ -133,7 +131,7 @@ import UIKit
|
||||
|
||||
/// If you're using a ViewController, you must set this to it
|
||||
public weak var uiTextFieldDelegate: UITextFieldDelegate? {
|
||||
get { return textField.delegate }
|
||||
get { textField.delegate }
|
||||
set { textField.delegate = newValue }
|
||||
}
|
||||
|
||||
@ -330,6 +328,7 @@ import UIKit
|
||||
break
|
||||
}
|
||||
|
||||
textField.accessibilityIdentifier = model.accessibilityIdentifier
|
||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||
setupTextFieldToolbar()
|
||||
|
||||
@ -25,9 +25,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "textField"
|
||||
}
|
||||
public override class var identifier: String { "textField" }
|
||||
|
||||
public var placeholder: String?
|
||||
public var enabledTextColor: Color = Color(uiColor: .mvmBlack)
|
||||
|
||||
@ -31,11 +31,11 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
//--------------------------------------------------
|
||||
|
||||
public var textViewEntryFieldModel: TextViewEntryFieldModel? {
|
||||
return model as? TextViewEntryFieldModel
|
||||
model as? TextViewEntryFieldModel
|
||||
}
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
get { return super.isEnabled }
|
||||
get { super.isEnabled }
|
||||
set (enabled) {
|
||||
super.isEnabled = enabled
|
||||
|
||||
@ -53,7 +53,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
}
|
||||
|
||||
public override var showError: Bool {
|
||||
get { return super.showError }
|
||||
get { super.showError }
|
||||
set (error) {
|
||||
|
||||
if error {
|
||||
@ -68,7 +68,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
|
||||
/// The text of this textView.
|
||||
open override var text: String? {
|
||||
get { return textViewEntryFieldModel?.text }
|
||||
get { textViewEntryFieldModel?.text }
|
||||
set {
|
||||
textView.text = newValue
|
||||
textViewEntryFieldModel?.text = newValue
|
||||
@ -77,7 +77,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
|
||||
/// Placeholder access for the textView.
|
||||
public var placeholder: String? {
|
||||
get { return textViewEntryFieldModel?.placeholder }
|
||||
get { textViewEntryFieldModel?.placeholder }
|
||||
set {
|
||||
textView.placeholder = newValue ?? ""
|
||||
textViewEntryFieldModel?.placeholder = newValue
|
||||
@ -127,7 +127,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
|
||||
/// If you're using a ViewController, you must set this to it
|
||||
public weak var uiTextViewDelegate: UITextViewDelegate? {
|
||||
get { return textView.delegate }
|
||||
get { textView.delegate }
|
||||
set { textView.delegate = newValue }
|
||||
}
|
||||
|
||||
@ -241,6 +241,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
|
||||
textView.isEditable = model.editable
|
||||
textView.textAlignment = model.textAlignment
|
||||
textView.accessibilityIdentifier = model.accessibilityIdentifier
|
||||
textView.textColor = model.enabled ? model.enabledTextColor.uiColor : model.disabledTextColor.uiColor
|
||||
textView.font = model.fontStyle.getFont()
|
||||
textView.placeholder = model.placeholder ?? ""
|
||||
@ -258,7 +259,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
||||
case .email:
|
||||
textView.keyboardType = .emailAddress
|
||||
|
||||
default: break
|
||||
default: break
|
||||
}
|
||||
|
||||
/// No point in configuring if the TextView is Read-only.
|
||||
|
||||
@ -14,9 +14,7 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class var identifier: String {
|
||||
return "textView"
|
||||
}
|
||||
public override class var identifier: String { "textView" }
|
||||
|
||||
public var accessibilityText: String?
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodyLarge
|
||||
|
||||
@ -25,7 +25,7 @@ import MVMCore
|
||||
var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
public var checkboxModel: CheckboxModel? {
|
||||
return model as? CheckboxModel
|
||||
model as? CheckboxModel
|
||||
}
|
||||
|
||||
public static let defaultHeightWidth: CGFloat = 18.0
|
||||
@ -59,7 +59,7 @@ import MVMCore
|
||||
|
||||
/// Retrieves ideeal radius value to curve square into a circle.
|
||||
public var cornerRadiusValue: CGFloat {
|
||||
return bounds.size.height / 2
|
||||
bounds.size.height / 2
|
||||
}
|
||||
|
||||
/// Action Block called when the switch is selected.
|
||||
@ -102,23 +102,17 @@ import MVMCore
|
||||
|
||||
/// Color of the check mark.
|
||||
public var checkColor: UIColor = .mvmBlack {
|
||||
didSet {
|
||||
setShapeLayerStrokeColor(checkColor)
|
||||
}
|
||||
didSet { setShapeLayerStrokeColor(checkColor) }
|
||||
}
|
||||
|
||||
/// Border width of the checkbox
|
||||
public var borderWidth: CGFloat = 1 {
|
||||
didSet {
|
||||
layer.borderWidth = borderWidth
|
||||
}
|
||||
didSet { layer.borderWidth = borderWidth }
|
||||
}
|
||||
|
||||
/// border color of the Checkbox
|
||||
public var borderColor: UIColor = .mvmBlack {
|
||||
didSet {
|
||||
layer.borderColor = borderColor.cgColor
|
||||
}
|
||||
didSet { layer.borderColor = borderColor.cgColor }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,6 +353,7 @@ import MVMCore
|
||||
}
|
||||
|
||||
override open func accessibilityActivate() -> Bool {
|
||||
guard isEnabled else { return false }
|
||||
sendActions(for: .touchUpInside)
|
||||
return true
|
||||
}
|
||||
@ -367,9 +362,7 @@ import MVMCore
|
||||
// MARK: - Molecular
|
||||
//--------------------------------------------------
|
||||
|
||||
open func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
open func needsToBeConstrained() -> Bool { true }
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
@ -16,6 +16,7 @@ import Foundation
|
||||
|
||||
public static var identifier: String = "checkbox"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var checked: Bool = false
|
||||
public var enabled: Bool = true
|
||||
public var animated: Bool = true
|
||||
@ -44,6 +45,7 @@ import Foundation
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case accessibilityIdentifier
|
||||
case checked
|
||||
case enabled
|
||||
case inverted
|
||||
@ -69,9 +71,7 @@ import Foundation
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return checked
|
||||
}
|
||||
public func formFieldValue() -> AnyHashable? { checked }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
@ -89,6 +89,8 @@ import Foundation
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) {
|
||||
self.borderWidth = borderWidth
|
||||
}
|
||||
@ -169,6 +171,7 @@ import Foundation
|
||||
try container.encode(borderWidth, forKey: .borderWidth)
|
||||
try container.encode(checked, forKey: .checked)
|
||||
try container.encode(inverted, forKey: .inverted)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeIfPresent(checkColor, forKey: .checkColor)
|
||||
try container.encodeIfPresent(invertedColor, forKey: .invertedColor)
|
||||
try container.encodeIfPresent(invertedBackgroundColor, forKey: .invertedBackgroundColor)
|
||||
|
||||
@ -71,6 +71,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
addTarget(self, action: #selector(tapAction), for: .touchUpInside)
|
||||
|
||||
@ -6,15 +6,16 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "heart"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var isActive: Bool = false
|
||||
public var activeColor: Color = Color(uiColor: .mvmRed)
|
||||
public var inActiveColor: Color = Color(uiColor: .clear)
|
||||
@ -24,9 +25,11 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case isActive
|
||||
case activeColor
|
||||
case inActiveColor
|
||||
@ -43,13 +46,18 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
||||
if let isActive = try typeContainer.decodeIfPresent(Bool.self, forKey: .isActive) {
|
||||
self.isActive = isActive
|
||||
}
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let activeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .activeColor) {
|
||||
self.activeColor = activeColor
|
||||
}
|
||||
|
||||
if let inActiveColor = try typeContainer.decodeIfPresent(Color.self, forKey: .inActiveColor) {
|
||||
self.inActiveColor = inActiveColor
|
||||
}
|
||||
|
||||
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
|
||||
self.action = action
|
||||
}
|
||||
@ -61,6 +69,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(isActive, forKey: .isActive)
|
||||
try container.encode(activeColor, forKey: .activeColor)
|
||||
|
||||
@ -6,9 +6,12 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class RadioBox: Control, MFButtonProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public let label = Label(fontStyle: .RegularBodySmall)
|
||||
public let subTextLabel = Label(fontStyle: .RegularMicro)
|
||||
public var isOutOfStock = false
|
||||
@ -26,22 +29,20 @@ open class RadioBox: Control, MFButtonProtocol {
|
||||
var additionalData: [AnyHashable: Any]?
|
||||
|
||||
public var radioBoxModel: RadioBoxModel? {
|
||||
return model as? RadioBoxModel
|
||||
model as? RadioBoxModel
|
||||
}
|
||||
|
||||
public override var isSelected: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
didSet { updateAccessibility() }
|
||||
}
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
updateAccessibility()
|
||||
}
|
||||
didSet { updateAccessibility() }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
@ -75,8 +76,6 @@ open class RadioBox: Control, MFButtonProtocol {
|
||||
isAccessibilityElement = true
|
||||
}
|
||||
|
||||
// MARK: - MoleculeViewProtocol
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
guard let model = model as? RadioBoxModel else { return }
|
||||
@ -99,7 +98,9 @@ open class RadioBox: Control, MFButtonProtocol {
|
||||
accentColor = .mvmRed
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - State Handling
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||
// Draw the strikethrough
|
||||
@ -213,21 +214,29 @@ open class RadioBox: Control, MFButtonProtocol {
|
||||
return mask
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Accessibility
|
||||
//--------------------------------------------------
|
||||
|
||||
public func updateAccessibility() {
|
||||
|
||||
var message = ""
|
||||
|
||||
if let labelText = label.text, label.hasText {
|
||||
message += labelText + ", "
|
||||
}
|
||||
|
||||
if let subLabelText = subTextLabel.text, subTextLabel.hasText {
|
||||
message += subLabelText + ", "
|
||||
}
|
||||
accessibilityLabel = message
|
||||
|
||||
accessibilityLabel = message
|
||||
accessibilityTraits = .button
|
||||
|
||||
if isSelected {
|
||||
accessibilityTraits.insert(.selected)
|
||||
}
|
||||
|
||||
if !isEnabled {
|
||||
accessibilityTraits.insert(.notEnabled)
|
||||
}
|
||||
|
||||
@ -6,10 +6,17 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
open class RadioBoxCollectionViewCell: CollectionViewCell {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
|
||||
public let radioBox = RadioBox()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
backgroundColor = .clear
|
||||
|
||||
@ -6,12 +6,16 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@objcMembers public class RadioBoxModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "radioBox"
|
||||
public var text: String
|
||||
public var subText: String?
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var selectedAccentColor: Color?
|
||||
public var selected: Bool = false
|
||||
public var enabled: Bool = true
|
||||
@ -19,12 +23,17 @@ import Foundation
|
||||
public var fieldValue: String?
|
||||
public var action: ActionModelProtocol?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case text
|
||||
case subText
|
||||
case selectedAccentColor
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case selected
|
||||
case enabled
|
||||
case strikethrough
|
||||
@ -32,18 +41,26 @@ import Foundation
|
||||
case action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
text = try typeContainer.decode(String.self, forKey: .text)
|
||||
subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText)
|
||||
selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
|
||||
selected = isSelected
|
||||
}
|
||||
|
||||
if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||
enabled = isEnabled
|
||||
}
|
||||
|
||||
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||
strikethrough = isStrikeTrough
|
||||
}
|
||||
@ -59,6 +76,7 @@ import Foundation
|
||||
try container.encodeIfPresent(subText, forKey: .subText)
|
||||
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(selected, forKey: .selected)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
try container.encode(strikethrough, forKey: .strikethrough)
|
||||
|
||||
@ -57,11 +57,12 @@ open class RadioBoxes: View {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
|
||||
guard let radioBoxesModel = model as? RadioBoxesModel else { return }
|
||||
boxes = radioBoxesModel.boxes
|
||||
FormValidator.setupValidation(for: radioBoxesModel, delegate: delegateObject?.formHolderDelegate)
|
||||
guard let model = model as? RadioBoxesModel else { return }
|
||||
boxes = model.boxes
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
|
||||
backgroundColor = radioBoxesModel.backgroundColor?.uiColor
|
||||
backgroundColor = model.backgroundColor?.uiColor
|
||||
|
||||
registerCells()
|
||||
setHeight()
|
||||
collectionView.reloadData()
|
||||
@ -168,4 +169,3 @@ extension RadioBoxes: UICollectionViewDelegate {
|
||||
cell.updateAccessibility()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,17 +6,25 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@objcMembers public class RadioBoxesModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "radioBoxes"
|
||||
public var boxes: [RadioBoxModel]
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var selectedAccentColor: Color?
|
||||
public var boxesColor: Color?
|
||||
public var fieldKey: String?
|
||||
public var groupName: String = FormValidator.defaultGroupName
|
||||
public var baseValue: AnyHashable?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
let selectedBox = boxes.first { (box) -> Bool in
|
||||
@ -25,20 +33,30 @@ import Foundation
|
||||
return selectedBox?.fieldValue ?? selectedBox?.text
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case selectedAccentColor
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case boxesColor
|
||||
case boxes
|
||||
case fieldKey
|
||||
case groupName
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
boxesColor = try typeContainer.decodeIfPresent(Color.self, forKey: .boxesColor)
|
||||
boxes = try typeContainer.decode([RadioBoxModel].self, forKey: .boxes)
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
@ -54,6 +72,7 @@ import Foundation
|
||||
try container.encode(boxes, forKey: .boxes)
|
||||
try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encode(groupName, forKey: .groupName)
|
||||
}
|
||||
|
||||
@ -15,9 +15,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public var diameter: CGFloat = 30 {
|
||||
didSet {
|
||||
widthConstraint?.constant = diameter
|
||||
}
|
||||
didSet { widthConstraint?.constant = diameter }
|
||||
}
|
||||
|
||||
@objc public override var isSelected: Bool {
|
||||
@ -33,12 +31,10 @@ import UIKit
|
||||
var additionalData: [AnyHashable: Any]?
|
||||
|
||||
public var radioModel: RadioButtonModel? {
|
||||
return model as? RadioButtonModel
|
||||
model as? RadioButtonModel
|
||||
}
|
||||
|
||||
lazy public var radioGroupName: String? = {
|
||||
return radioModel?.fieldKey
|
||||
}()
|
||||
lazy public var radioGroupName: String? = { radioModel?.fieldKey }()
|
||||
|
||||
lazy public var radioButtonSelectionHelper: RadioButtonSelectionHelper? = {
|
||||
|
||||
@ -95,33 +91,34 @@ import UIKit
|
||||
if !isEnabled {
|
||||
return
|
||||
}
|
||||
|
||||
let wasPreviouslySelected = isSelected
|
||||
if let radioButtonModel = radioButtonSelectionHelper {
|
||||
radioButtonModel.selected(self)
|
||||
} else {
|
||||
isSelected = !isSelected
|
||||
}
|
||||
|
||||
if let radioModel = radioModel, let actionModel = radioModel.action, isSelected, !wasPreviouslySelected {
|
||||
Button.performButtonAction(with: actionModel, button: self, delegateObject: delegateObject, additionalData: additionalData, sourceModel: radioModel)
|
||||
}
|
||||
|
||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
public func isValidField() -> Bool {
|
||||
return isSelected
|
||||
}
|
||||
public func isValidField() -> Bool { isSelected }
|
||||
|
||||
public func formFieldName() -> String? {
|
||||
return radioModel?.fieldKey
|
||||
radioModel?.fieldKey
|
||||
}
|
||||
|
||||
public func formFieldGroupName() -> String? {
|
||||
return radioModel?.fieldKey
|
||||
radioModel?.fieldKey
|
||||
}
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return radioModel?.fieldValue
|
||||
radioModel?.fieldValue
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MVMCore
|
||||
|
||||
|
||||
@ -17,6 +16,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
|
||||
public static var identifier: String = "radioButton"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var state: Bool = false
|
||||
public var enabled: Bool = true
|
||||
|
||||
@ -35,6 +35,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case state
|
||||
case enabled
|
||||
case fieldValue
|
||||
@ -56,9 +57,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
// MARK: - Validation
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return fieldValue
|
||||
}
|
||||
public func formFieldValue() -> AnyHashable? { fieldValue }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
@ -76,6 +75,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
}
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
baseValue = state
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
@ -89,6 +89,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(state, forKey: .state)
|
||||
try container.encode(enabled, forKey: .enabled)
|
||||
|
||||
@ -6,8 +6,6 @@
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
@objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol {
|
||||
//--------------------------------------------------
|
||||
@ -77,7 +75,5 @@ import Foundation
|
||||
// MARK: - FormValidationFormFieldProtocol
|
||||
extension RadioButtonSelectionHelper {
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return selectedRadioButtonModel?.fieldValue
|
||||
}
|
||||
public func formFieldValue() -> AnyHashable? { selectedRadioButtonModel?.fieldValue }
|
||||
}
|
||||
|
||||
@ -77,6 +77,7 @@ open class RadioSwatch: Control, MFButtonProtocol {
|
||||
//------------------------------------------------------
|
||||
// MARK: - State Handling
|
||||
//------------------------------------------------------
|
||||
|
||||
open override func draw(_ layer: CALayer, in ctx: CGContext) {
|
||||
//Draw the swatch
|
||||
circleLayer?.removeFromSuperlayer()
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class RadioSwatchCollectionViewCell: CollectionViewCell {
|
||||
public let radioSwatch = RadioSwatch()
|
||||
|
||||
|
||||
@ -6,11 +6,15 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class RadioSwatchModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "radioSwatch"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var color: Color = Color(uiColor: .mvmBlue)
|
||||
public var text: String?
|
||||
public var selected: Bool = false
|
||||
@ -19,9 +23,14 @@ import Foundation
|
||||
public var fieldValue: String?
|
||||
public var action: ActionModelProtocol?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case color
|
||||
case text
|
||||
case selected
|
||||
@ -31,22 +40,33 @@ import Foundation
|
||||
case action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) {
|
||||
self.color = color
|
||||
}
|
||||
|
||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||
|
||||
if let selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected) {
|
||||
self.selected = selected
|
||||
}
|
||||
|
||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||
self.enabled = enabled
|
||||
}
|
||||
|
||||
if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||
self.strikethrough = strikethrough
|
||||
}
|
||||
|
||||
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||
}
|
||||
@ -55,6 +75,7 @@ import Foundation
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(color, forKey: .color)
|
||||
try container.encodeIfPresent(text, forKey: .text)
|
||||
try container.encode(selected, forKey: .selected)
|
||||
@ -64,5 +85,3 @@ import Foundation
|
||||
try container.encodeModelIfPresent(action, forKey: .action)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -55,9 +55,9 @@ open class RadioSwatches: View {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
|
||||
guard let radioSwatchesModel = model as? RadioSwatchesModel else { return }
|
||||
swatches = radioSwatchesModel.swatches
|
||||
FormValidator.setupValidation(for: radioSwatchesModel, delegate: delegateObject?.formHolderDelegate)
|
||||
guard let model = model as? RadioSwatchesModel else { return }
|
||||
swatches = model.swatches
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
collectionView.reloadData()
|
||||
}
|
||||
|
||||
|
||||
@ -6,16 +6,24 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class RadioSwatchesModel: MoleculeModelProtocol, FormFieldProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "radioSwatches"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var swatches: [RadioSwatchModel]
|
||||
public var fieldKey: String?
|
||||
public var groupName: String = FormValidator.defaultGroupName
|
||||
public var baseValue: AnyHashable?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Returns the fieldValue of the selected swatch, otherwise the text of selected swatch.
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
let selectedSwatch = swatches.first { (swatch) -> Bool in
|
||||
@ -24,17 +32,27 @@ import Foundation
|
||||
return selectedSwatch?.fieldValue ?? selectedSwatch?.text
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case swatches
|
||||
case fieldKey
|
||||
case groupName
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches)
|
||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||
@ -47,6 +65,7 @@ import Foundation
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(swatches, forKey: .swatches)
|
||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||
try container.encode(groupName, forKey: .groupName)
|
||||
|
||||
@ -40,7 +40,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
/// Executes logic before state change. If false, then toggle state will not change and the didToggleAction will not execute.
|
||||
public var shouldToggleAction: ActionBlockConfirmation? = {
|
||||
return { return true }
|
||||
return { true }
|
||||
}()
|
||||
|
||||
// Sizes are from InVision design specs.
|
||||
@ -69,9 +69,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
|
||||
/// Simple means to prevent user interaction with the toggle.
|
||||
public var isLocked: Bool = false {
|
||||
didSet {
|
||||
isUserInteractionEnabled = !isLocked
|
||||
}
|
||||
didSet { isUserInteractionEnabled = !isLocked }
|
||||
}
|
||||
|
||||
/// The state on the toggle. Default value: false.
|
||||
@ -109,7 +107,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
}
|
||||
|
||||
public var toggleModel: ToggleModel? {
|
||||
return model as? ToggleModel
|
||||
model as? ToggleModel
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -410,18 +408,14 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return Self.getContainerHeight()
|
||||
Self.getContainerHeight()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
extension Toggle {
|
||||
|
||||
public func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
public func needsToBeConstrained() -> Bool { true }
|
||||
|
||||
public func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .trailing
|
||||
}
|
||||
public func horizontalAlignment() -> UIStackView.Alignment { .trailing }
|
||||
}
|
||||
@ -6,8 +6,6 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol {
|
||||
//--------------------------------------------------
|
||||
@ -15,6 +13,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "toggle"
|
||||
public var accessibilityIdentifier: String?
|
||||
public var backgroundColor: Color?
|
||||
public var state: Bool = false
|
||||
public var animated: Bool = true
|
||||
@ -42,6 +41,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
case enabled
|
||||
case action
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case alternateAction
|
||||
case accessibilityText
|
||||
case onTintColor
|
||||
@ -56,9 +56,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return state
|
||||
}
|
||||
public func formFieldValue() -> AnyHashable? { state }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
@ -91,6 +89,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||
alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let onTintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .onTintColor) {
|
||||
self.onTintColor = onTintColor
|
||||
@ -120,6 +119,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encodeModelIfPresent(action, forKey: .action)
|
||||
try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
@ -16,6 +16,7 @@ import Foundation
|
||||
|
||||
public static var identifier: String = "dashLine"
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public var dashColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var dashColor_inverted: Color = Color(uiColor: .mvmWhite)
|
||||
public var isHidden: Bool = false
|
||||
@ -36,6 +37,7 @@ import Foundation
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case dashColor_inverted
|
||||
case dashColor
|
||||
case isHidden
|
||||
@ -57,6 +59,7 @@ import Foundation
|
||||
}
|
||||
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
|
||||
if let isHidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .isHidden) {
|
||||
self.isHidden = isHidden
|
||||
@ -69,5 +72,6 @@ import Foundation
|
||||
try container.encode(dashColor, forKey: .dashColor)
|
||||
try container.encode(isHidden, forKey: .isHidden)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
|
||||
public var getRange: NSRange {
|
||||
return NSRange(location: 0, length: text?.count ?? 0)
|
||||
NSRange(location: 0, length: text?.count ?? 0)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
@ -209,7 +209,7 @@ public typealias ActionBlock = () -> ()
|
||||
|
||||
/// Default
|
||||
@objc open class func label() -> Label {
|
||||
return Label(frame: .zero)
|
||||
Label(frame: .zero)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
@ -792,17 +792,11 @@ extension Label {
|
||||
accessibilityTraits = .staticText
|
||||
}
|
||||
|
||||
public func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
public func needsToBeConstrained() -> Bool { true }
|
||||
|
||||
public func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .leading
|
||||
}
|
||||
public func horizontalAlignment() -> UIStackView.Alignment { .leading }
|
||||
|
||||
public func copyBackgroundColor() -> Bool {
|
||||
return true
|
||||
}
|
||||
public func copyBackgroundColor() -> Bool { true }
|
||||
}
|
||||
|
||||
// MARK: - Multi-Link Functionality
|
||||
@ -914,6 +908,7 @@ extension UITapGestureRecognizer {
|
||||
if label.makeWholeViewClickable {
|
||||
return true
|
||||
}
|
||||
|
||||
guard let abstractContainer = label.abstractTextContainer() else { return false }
|
||||
let textContainer = abstractContainer.0
|
||||
let layoutManager = abstractContainer.1
|
||||
@ -988,6 +983,7 @@ extension Label {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,7 @@ open class LabelAttributeActionModel: LabelAttributeModel {
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "action"
|
||||
}
|
||||
override public class var identifier: String { "action" }
|
||||
|
||||
var action: ActionModelProtocol
|
||||
|
||||
|
||||
@ -12,9 +12,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "color"
|
||||
}
|
||||
override public class var identifier: String { "color" }
|
||||
|
||||
var textColor: Color?
|
||||
|
||||
|
||||
@ -12,9 +12,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "font"
|
||||
}
|
||||
override public class var identifier: String { "font" }
|
||||
|
||||
var style: Styler.Font?
|
||||
var name: String?
|
||||
|
||||
@ -12,9 +12,7 @@ class LabelAttributeImageModel: LabelAttributeModel {
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "image"
|
||||
}
|
||||
override public class var identifier: String { "image" }
|
||||
|
||||
var size: CGFloat?
|
||||
var name: String?
|
||||
|
||||
@ -12,20 +12,14 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var categoryName: String {
|
||||
return "\(LabelAttributeModel.self)"
|
||||
}
|
||||
public static var categoryName: String { "\(LabelAttributeModel.self)" }
|
||||
|
||||
public static var categoryCodingKey: String {
|
||||
return "type"
|
||||
}
|
||||
public static var categoryCodingKey: String { "type" }
|
||||
|
||||
public class var identifier: String {
|
||||
return ""
|
||||
}
|
||||
public class var identifier: String { "" }
|
||||
|
||||
var type: String {
|
||||
get { return Self.identifier }
|
||||
get { Self.identifier }
|
||||
}
|
||||
|
||||
var location: Int
|
||||
|
||||
@ -12,9 +12,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "strikethrough"
|
||||
}
|
||||
override public class var identifier: String { "strikethrough" }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
|
||||
@ -14,9 +14,7 @@ import UIKit
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
override public class var identifier: String {
|
||||
return "underline"
|
||||
}
|
||||
override public class var identifier: String { "underline" }
|
||||
|
||||
/// This returns the NSUnderlineStyle used in NSAttributedValue. If there is a pattern, it will return
|
||||
/// a new NSUnderlineStyle derived from the bitmask of style | pattern.
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
}
|
||||
|
||||
// Constrains the image view to be the size provided. Used to size it to the image to fix aspect fit defect.
|
||||
func addConstraints(width: NSNumber?, height: NSNumber?, size: CGSize?) {
|
||||
func addConstraints(width: CGFloat?, height: CGFloat?, size: CGSize?) {
|
||||
|
||||
widthConstraint?.isActive = false
|
||||
heightConstraint?.isActive = false
|
||||
@ -242,15 +242,15 @@
|
||||
guard addSizeConstraintsForAspectRatio else { return }
|
||||
|
||||
if let width = width, let height = height {
|
||||
setHeight(height.cgfloat())
|
||||
setWidth(width.cgfloat())
|
||||
setHeight(height)
|
||||
setWidth(width)
|
||||
} else if let width = width, let size = size {
|
||||
setWidth(width.cgfloat())
|
||||
setWidth(width)
|
||||
heightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: size.height/size.width)
|
||||
heightConstraint?.priority = UILayoutPriority(rawValue: 900)
|
||||
heightConstraint?.isActive = true
|
||||
} else if let height = height, let size = size {
|
||||
setHeight(height.cgfloat())
|
||||
setHeight(height)
|
||||
widthConstraint = imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor, multiplier: size.width/size.height)
|
||||
widthConstraint?.priority = UILayoutPriority(rawValue: 900)
|
||||
widthConstraint?.isActive = true
|
||||
@ -288,7 +288,7 @@
|
||||
if shouldLoadImage(withName: imageModel.image, width: width, height: height) {
|
||||
imageView.image = nil
|
||||
imageView.animatedImage = nil
|
||||
loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width as NSNumber?, height: height as NSNumber?, customFallbackImage: imageModel.fallbackImage, localBundle: imageModel.localBundle)
|
||||
loadImage(withName: imageModel.image, format: imageModel.imageFormat, width: width, height: height, customFallbackImage: imageModel.fallbackImage, localBundle: imageModel.localBundle)
|
||||
}
|
||||
|
||||
if let contentMode = imageModel.contentMode {
|
||||
@ -309,13 +309,13 @@
|
||||
// MARK: - Load Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func loadImage(withName imageName: String?, format: String? = nil, width: NSNumber? = nil, height: NSNumber? = nil, customFallbackImage: String? = nil, allowServerParameters: Bool = false, localBundle: Bundle? = nil, completionHandler: MVMCoreGetImageBlock? = nil) {
|
||||
public func loadImage(withName imageName: String?, format: String? = nil, width: CGFloat? = nil, height: CGFloat? = nil, customFallbackImage: String? = nil, allowServerParameters: Bool = false, localBundle: Bundle? = nil, completionHandler: MVMCoreGetImageBlock? = nil) {
|
||||
|
||||
let completionBlock = completionHandler ?? defaultCompletionBlock()
|
||||
MVMCoreDispatchUtility.performBlock(onMainThread: { [unowned self] in
|
||||
self.currentImageName = imageName
|
||||
self.currentImageWidth = width?.cgfloat()
|
||||
self.currentImageHeight = height?.cgfloat()
|
||||
self.currentImageWidth = width
|
||||
self.currentImageHeight = height
|
||||
if MVMCoreCache.isHostedImage(imageName) {
|
||||
self.loadingSpinner.resumeSpinnerAfterDelay()
|
||||
self.loadingSpinnerHeightConstraint?.constant = self.spinnerHeight
|
||||
@ -338,9 +338,9 @@
|
||||
let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback")
|
||||
if let format = format, format.lowercased().contains("gif") {
|
||||
// Gifs aren't supported by default and need special handling
|
||||
MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||
MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: Int(width ?? 0), useHeight: height != nil, heightForS7: Int(height ?? 0), format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||
} else {
|
||||
MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||
MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: Int(width ?? 0), useHeight: height != nil, heightForS7: Int(height ?? 0), format: format, localFallbackImageName: fallbackImageName, allowServerQueryParameters: allowServerParameters, localBundle: localBundle, completionHandler: finishedLoadingBlock)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -409,6 +409,6 @@
|
||||
}
|
||||
|
||||
public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?, completionHandler: @escaping MVMCoreGetImageBlock) {
|
||||
loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, allowServerParameters: false, completionHandler: completionHandler)
|
||||
loadImage(withName: imageName, format: format, width: width?.cgfloat(), height: height?.cgfloat(), customFallbackImage: customFallbackImage, allowServerParameters: false, completionHandler: completionHandler)
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ import UIKit
|
||||
private let stack = Stack<StackModel>()
|
||||
|
||||
var multiProgressModel: MultiProgressBarModel? {
|
||||
get { return model as? MultiProgressBarModel }
|
||||
get { model as? MultiProgressBarModel }
|
||||
}
|
||||
|
||||
var roundedCorners: Bool = false {
|
||||
@ -85,7 +85,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Creates the bars
|
||||
open func set(with progressList: Array<SingleProgressBarModel>, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
open func set(with progressList: [SingleProgressBarModel], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
stack.removeAllItemViews()
|
||||
|
||||
guard let stackModel = stack.stackModel else { return }
|
||||
@ -103,7 +103,6 @@ import UIKit
|
||||
stack.set(with: stackModel, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
|
||||
@ -115,6 +114,6 @@ import UIKit
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return (model as? MultiProgressBarModel)?.thickness ?? 8
|
||||
(model as? MultiProgressBarModel)?.thickness ?? 8
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class HeaderView: Container {
|
||||
public let line = Line()
|
||||
@ -15,7 +14,7 @@ open class HeaderView: Container {
|
||||
open var molecule: MoleculeViewProtocol?
|
||||
|
||||
var headerModel: HeaderModel? {
|
||||
get { return model as? HeaderModel }
|
||||
get { model as? HeaderModel }
|
||||
}
|
||||
|
||||
/// Convenience function to add a molecule to the view.
|
||||
@ -58,6 +57,6 @@ open class HeaderView: Container {
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
|
||||
PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class MoleculeHeaderModel: HeaderModel, MoleculeModelProtocol, MoleculeContainerModelProtocol {
|
||||
public static var identifier: String = "header"
|
||||
|
||||
@ -17,7 +17,7 @@ public class MoleculeHeaderView: MoleculeContainer {
|
||||
var line = Line()
|
||||
|
||||
var headerModel: MoleculeHeaderModel? {
|
||||
get { return model as? MoleculeHeaderModel }
|
||||
get { model as? MoleculeHeaderModel }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class TabBar: UITabBar, MoleculeViewProtocol, TabBarProtocol, UITabBarDelegate {
|
||||
|
||||
@ -15,9 +14,7 @@ import Foundation
|
||||
public let line = Line()
|
||||
|
||||
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? TabBarModel else {
|
||||
fatalError("model is not TabBarModel")
|
||||
}
|
||||
guard let model = model as? TabBarModel else { fatalError("model is not TabBarModel") }
|
||||
self.model = model
|
||||
super.init(frame: .zero)
|
||||
|
||||
@ -32,7 +29,7 @@ import Foundation
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? TabBarModel else { return }
|
||||
self.model = model
|
||||
|
||||
@ -57,8 +54,12 @@ import Foundation
|
||||
var tabs: [UITabBarItem] = []
|
||||
for (index, tab) in model.tabs.enumerated() {
|
||||
let tabBarItem = UITabBarItem(title: tab.title, image: MVMCoreCache.shared()?.getImageFromRegisteredBundles(tab.image), tag: index)
|
||||
tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
||||
tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: MFFonts.mfFontTXRegular(8)], for: .normal)
|
||||
tabBarItem.accessibilityLabel = tab.accessibilityText
|
||||
if #available(iOS 13.0, *) {
|
||||
} else {
|
||||
tabBarItem.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -3)
|
||||
tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: MFFonts.mfFontTXRegular(8)], for: .normal)
|
||||
}
|
||||
tabs.append(tabBarItem)
|
||||
}
|
||||
setItems(tabs, animated: false)
|
||||
@ -100,10 +101,7 @@ import Foundation
|
||||
})
|
||||
}
|
||||
|
||||
public func currentTabIndex() -> Int {
|
||||
return model.selectedTab
|
||||
}
|
||||
public func currentTabIndex() -> Int { model.selectedTab }
|
||||
}
|
||||
|
||||
extension UITabBarItem: MFButtonProtocol {
|
||||
}
|
||||
extension UITabBarItem: MFButtonProtocol { }
|
||||
|
||||
@ -63,11 +63,13 @@ public class TabBarItemModel: Codable {
|
||||
var title: String?
|
||||
var image: String
|
||||
var action: ActionModelProtocol
|
||||
var accessibilityText: String?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case title
|
||||
case image
|
||||
case action
|
||||
case accessibilityText
|
||||
}
|
||||
|
||||
public init(with title: String?, image: String, action: ActionModelProtocol) {
|
||||
@ -81,6 +83,7 @@ public class TabBarItemModel: Codable {
|
||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||
image = try typeContainer.decode(String.self, forKey: .image)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -88,5 +91,6 @@ public class TabBarItemModel: Codable {
|
||||
try container.encodeIfPresent(title, forKey: .title)
|
||||
try container.encode(image, forKey: .image)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,17 +6,15 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class ImageBarButtonItem: BarButtonItem {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public static func create(with image: UIImage?) -> Self {
|
||||
let actionObject = ActionDelegate()
|
||||
let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:)))
|
||||
let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock))
|
||||
button.actionDelegate = actionObject
|
||||
return button
|
||||
}
|
||||
@ -29,7 +27,7 @@ import Foundation
|
||||
}
|
||||
|
||||
/// Creates the item with the passed in action map.
|
||||
public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
|
||||
public static func create(with image: UIImage?, actionMap: [AnyHashable: Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self {
|
||||
let button = create(with: image)
|
||||
button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
return button
|
||||
@ -42,4 +40,3 @@ import Foundation
|
||||
return button
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,10 +6,8 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class LabelBarButtonItem: BarButtonItem {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -5,30 +5,47 @@
|
||||
// Created by Scott Pfeil on 5/18/20.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class NavigationImageButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public var accessibilityIdentifier: String?
|
||||
public static var identifier: String = "navigationImageButton"
|
||||
|
||||
public var image: String
|
||||
public var action: ActionModelProtocol
|
||||
public var accessibilityText: String?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(with image: String, action: ActionModelProtocol) {
|
||||
self.image = image
|
||||
self.action = action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Coding Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case image
|
||||
case action
|
||||
case accessibilityIdentifier
|
||||
case moleculeName
|
||||
case accessibilityText
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
image = try typeContainer.decode(String.self, forKey: .image)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText)
|
||||
@ -37,19 +54,26 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(image, forKey: .image)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Method
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Convenience function that creates a BarButtonItem for the model.
|
||||
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem {
|
||||
let uiImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(image)
|
||||
let navigationImageButton = ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
let buttonItem = ImageBarButtonItem.create(with: uiImage, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
buttonItem.accessibilityIdentifier = accessibilityIdentifier ?? image
|
||||
if let accessibilityString = accessibilityText {
|
||||
navigationImageButton.accessibilityLabel = accessibilityString
|
||||
navigationImageButton.isAccessibilityElement = true
|
||||
buttonItem.accessibilityLabel = accessibilityString
|
||||
buttonItem.isAccessibilityElement = true
|
||||
}
|
||||
return navigationImageButton
|
||||
|
||||
return buttonItem
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,28 +6,45 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var backgroundColor: Color?
|
||||
public static var identifier: String = "navigationLabelButton"
|
||||
|
||||
public var accessibilityIdentifier: String?
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(with title: String, action: ActionModelProtocol) {
|
||||
self.title = title
|
||||
self.action = action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case accessibilityIdentifier
|
||||
case title
|
||||
case action
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
title = try typeContainer.decode(String.self, forKey: .title)
|
||||
action = try typeContainer.decodeModel(codingKey: .action)
|
||||
}
|
||||
@ -35,10 +52,15 @@ public class NavigationLabelButtonModel: NavigationButtonModelProtocol, Molecule
|
||||
open func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(title, forKey: .title)
|
||||
try container.encodeModel(action, forKey: .action)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Convenience function that creates a BarButtonItem for the model.
|
||||
public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> UIBarButtonItem {
|
||||
return LabelBarButtonItem.create(with: title, actionModel: action, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
@ -6,12 +6,13 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtocol {
|
||||
open class var identifier: String {
|
||||
return "navigationBar"
|
||||
}
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
open class var identifier: String { "navigationBar" }
|
||||
|
||||
open var title: String?
|
||||
open var hidden: Bool
|
||||
@ -28,13 +29,21 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
|
||||
open var additionalRightButtons: [(NavigationButtonModelProtocol & MoleculeModelProtocol)]?
|
||||
open var titleView: MoleculeModelProtocol?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init() {
|
||||
hidden = false
|
||||
backgroundColor = Color(uiColor: .white)
|
||||
tintColor = Color(uiColor: .black)
|
||||
backgroundColor = Color(uiColor: .mvmWhite)
|
||||
tintColor = Color(uiColor: .mvmBlack)
|
||||
line = LineModel(type: .standard)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case title
|
||||
@ -48,13 +57,17 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc
|
||||
case additionalRightButtons
|
||||
case titleView
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||
hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) ?? false
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white)
|
||||
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .mvmWhite)
|
||||
tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .mvmBlack)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .standard)
|
||||
alwaysShowBackButton = try typeContainer.decodeIfPresent(Bool.self, forKey: .alwaysShowBackButton)
|
||||
backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton)
|
||||
|
||||
@ -6,11 +6,10 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension MVMCoreUITopAlertExpandableView: MoleculeViewProtocol {
|
||||
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
defaultSetup()
|
||||
guard let model = model as? CollapsableNotificationModel else { return }
|
||||
backgroundColor = model.backgroundColor?.uiColor ?? .mvmGreen
|
||||
@ -30,6 +29,10 @@ extension MVMCoreUITopAlertExpandableView: MoleculeViewProtocol {
|
||||
MVMCoreUITopAlertBaseView.addAction(to: button, actionMap: topActionMap, additionalData: nil)
|
||||
shortView?.label?.accessibilityTraits = .button
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,17 +6,24 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension MVMCoreUITopAlertMainView: MoleculeViewProtocol {
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
defaultSetup()
|
||||
guard let model = model as? NotificationModel else { return }
|
||||
|
||||
backgroundColor = model.backgroundColor?.uiColor ?? .mvmGreen
|
||||
var actionMap = model.button?.action.toJSON()
|
||||
|
||||
if let title = model.button?.title {
|
||||
actionMap?.updateValue(title, forKey: KeyTitle)
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
|
||||
setupCloseButton(model.closeButton != nil, animationDelegate: MVMCoreUITopAlertView.sharedGlobal()?.animationDelegate)
|
||||
setup(withMessage: model.headline.text, subMessage: model.body?.text, color: model.headline.textColor?.uiColor ?? .white, actionMap: actionMap, additionalData: nil)
|
||||
}
|
||||
|
||||
@ -6,52 +6,72 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class NotificationModel: MoleculeModelProtocol {
|
||||
public class var identifier: String {
|
||||
return "notification"
|
||||
}
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public class var identifier: String { "notification" }
|
||||
public var accessibilityIdentifier: String?
|
||||
public var backgroundColor: Color?
|
||||
public var headline: LabelModel
|
||||
public var body: LabelModel?
|
||||
public var button: ButtonModel?
|
||||
public var closeButton: NotificationXButtonModel?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(with headline: LabelModel) {
|
||||
self.headline = headline
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Default
|
||||
//--------------------------------------------------
|
||||
|
||||
open func setDefault() {
|
||||
if backgroundColor == nil {
|
||||
backgroundColor = Color(uiColor: .mvmGreen())
|
||||
backgroundColor = Color(uiColor: .mvmGreen)
|
||||
}
|
||||
if headline.textColor == nil {
|
||||
headline.textColor = Color(uiColor: .white)
|
||||
headline.textColor = Color(uiColor: .mvmWhite)
|
||||
}
|
||||
if body?.textColor == nil {
|
||||
body?.textColor = Color(uiColor: .white)
|
||||
body?.textColor = Color(uiColor: .mvmWhite)
|
||||
}
|
||||
if button?.style == nil {
|
||||
button?.style = .secondary
|
||||
}
|
||||
button?.size = .tiny
|
||||
button?.enabledTextColor = Color(uiColor: .white)
|
||||
button?.enabledBorderColor = Color(uiColor: .white)
|
||||
button?.enabledTextColor = Color(uiColor: .mvmWhite)
|
||||
button?.enabledBorderColor = Color(uiColor: .mvmWhite)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Coding Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case accessibilityIdentifier
|
||||
case headline
|
||||
case body
|
||||
case button
|
||||
case closeButton
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
|
||||
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||
button = try typeContainer.decodeIfPresent(ButtonModel.self, forKey: .button)
|
||||
@ -63,6 +83,7 @@ open class NotificationModel: MoleculeModelProtocol {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||
try container.encode(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(button, forKey: .button)
|
||||
|
||||
@ -19,19 +19,15 @@ open class HeadlineBody: View {
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
|
||||
var spaceBetweenLabelsConstant = PaddingOne
|
||||
var spaceBetweenLabelsConstant = Padding.One
|
||||
var spaceBetweenLabels: NSLayoutConstraint?
|
||||
var leftConstraintTitle: NSLayoutConstraint?
|
||||
var rightConstraintTitle: NSLayoutConstraint?
|
||||
var leftConstraintMessage: NSLayoutConstraint?
|
||||
var rightConstraintMessage: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
func hasText() -> Bool {
|
||||
return headlineLabel.hasText || messageLabel.hasText
|
||||
headlineLabel.hasText || messageLabel.hasText
|
||||
}
|
||||
|
||||
// MARK: - Styling
|
||||
@ -54,25 +50,25 @@ open class HeadlineBody: View {
|
||||
}
|
||||
}
|
||||
|
||||
func styleLandingPageHeader() {
|
||||
public func styleLandingPageHeader() {
|
||||
headlineLabel.setFontStyle(.Title2XLarge)
|
||||
messageLabel.setFontStyle(.RegularBodySmall)
|
||||
spaceBetweenLabelsConstant = PaddingTwo
|
||||
spaceBetweenLabelsConstant = Padding.Two
|
||||
}
|
||||
|
||||
func stylePageHeader() {
|
||||
public func stylePageHeader() {
|
||||
headlineLabel.setFontStyle(.BoldTitleLarge)
|
||||
messageLabel.setFontStyle(.RegularBodySmall)
|
||||
spaceBetweenLabelsConstant = PaddingOne
|
||||
spaceBetweenLabelsConstant = Padding.One
|
||||
}
|
||||
|
||||
func styleListItem() {
|
||||
public func styleListItem() {
|
||||
headlineLabel.setFontStyle(.BoldBodySmall)
|
||||
messageLabel.setFontStyle(.RegularBodySmall)
|
||||
spaceBetweenLabelsConstant = 0
|
||||
}
|
||||
|
||||
func styleListItemDivider() {
|
||||
public func styleListItemDivider() {
|
||||
headlineLabel.setFontStyle(.BoldTitleMedium)
|
||||
messageLabel.setFontStyle(.RegularBodySmall)
|
||||
spaceBetweenLabelsConstant = 0
|
||||
@ -86,48 +82,41 @@ open class HeadlineBody: View {
|
||||
super.setupView()
|
||||
|
||||
backgroundColor = .clear
|
||||
clipsToBounds = true
|
||||
isAccessibilityElement = false
|
||||
shouldGroupAccessibilityChildren = true
|
||||
accessibilityElements = [headlineLabel, messageLabel]
|
||||
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
addSubview(view)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: view)
|
||||
|
||||
view.isAccessibilityElement = false
|
||||
view.shouldGroupAccessibilityChildren = true
|
||||
view.accessibilityElements = [headlineLabel, messageLabel]
|
||||
|
||||
view.addSubview(headlineLabel)
|
||||
view.addSubview(messageLabel)
|
||||
addSubview(headlineLabel)
|
||||
addSubview(messageLabel)
|
||||
|
||||
headlineLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
headlineLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||
messageLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
messageLabel.setContentHuggingPriority(.required, for: .vertical)
|
||||
view.setContentHuggingPriority(.required, for: .vertical)
|
||||
|
||||
headlineLabel.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
|
||||
headlineLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
|
||||
spaceBetweenLabels = messageLabel.topAnchor.constraint(equalTo: headlineLabel.bottomAnchor, constant: spaceBetweenLabelsConstant)
|
||||
spaceBetweenLabels?.isActive = true
|
||||
|
||||
leftConstraintTitle = headlineLabel.leftAnchor.constraint(equalTo: view.leftAnchor)
|
||||
leftConstraintTitle?.isActive = true
|
||||
|
||||
rightConstraintTitle = view.rightAnchor.constraint(equalTo: headlineLabel.rightAnchor)
|
||||
rightConstraintTitle?.isActive = true
|
||||
|
||||
leftConstraintMessage = messageLabel.leftAnchor.constraint(equalTo: view.leftAnchor)
|
||||
leftConstraintMessage?.isActive = true
|
||||
|
||||
rightConstraintMessage = view.rightAnchor.constraint(equalTo: messageLabel.rightAnchor)
|
||||
rightConstraintMessage?.isActive = true
|
||||
|
||||
view.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor).isActive = true
|
||||
NSLayoutConstraint.activate([
|
||||
headlineLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingAnchor.constraint(equalTo: headlineLabel.trailingAnchor),
|
||||
messageLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
trailingAnchor.constraint(equalTo: messageLabel.trailingAnchor),
|
||||
bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor)
|
||||
])
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
setSpacing()
|
||||
headlineLabel.updateView(size)
|
||||
messageLabel.updateView(size)
|
||||
setSpacing()
|
||||
|
||||
// Provide the label additional size information to help calculate its intrinsic height.
|
||||
let padding = MFStyler.defaultHorizontalPadding(forSize: size) * 2
|
||||
messageLabel.preferredMaxLayoutWidth = size - padding
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -146,19 +135,18 @@ open class HeadlineBody: View {
|
||||
// MARK: - MoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 58
|
||||
}
|
||||
public override class func estimatedHeight(with model: MoleculeModelProtocol,
|
||||
_ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 58 }
|
||||
|
||||
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
|
||||
guard let headlineBodyModel = model as? HeadlineBodyModel else { return }
|
||||
guard let model = model as? HeadlineBodyModel else { return }
|
||||
|
||||
style(with: headlineBodyModel.style)
|
||||
style(with: model.style)
|
||||
|
||||
headlineLabel.setOptional(with: headlineBodyModel.headline, delegateObject, additionalData)
|
||||
messageLabel.setOptional(with: headlineBodyModel.body, delegateObject, additionalData)
|
||||
headlineLabel.setOptional(with: model.headline, delegateObject, additionalData)
|
||||
messageLabel.setOptional(with: model.body, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
|
||||
@ -16,7 +16,7 @@ open class Stack<T>: Container where T: (StackModelProtocol & MoleculeModelProto
|
||||
open var stackItems: [UIView] = []
|
||||
|
||||
open var stackModel: T? {
|
||||
get { return model as? T }
|
||||
get { model as? T }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
//
|
||||
// AccessibilityModelProtocol.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 2/3/21.
|
||||
// Copyright © 2021 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol AccessibilityModelProtocol {
|
||||
|
||||
var accessibilityIdentifier: String? { get set }
|
||||
}
|
||||
|
||||
public extension AccessibilityModelProtocol {
|
||||
|
||||
var accessibilityIdentifier: String? {
|
||||
get { nil }
|
||||
set { }
|
||||
}
|
||||
}
|
||||
@ -7,22 +7,16 @@ public enum MolecularError: Swift.Error {
|
||||
}
|
||||
|
||||
|
||||
public protocol MoleculeModelProtocol: ModelProtocol {
|
||||
public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol {
|
||||
var moleculeName: String { get }
|
||||
var backgroundColor: Color? { get set }
|
||||
}
|
||||
|
||||
public extension MoleculeModelProtocol {
|
||||
|
||||
var moleculeName: String {
|
||||
get { return Self.identifier }
|
||||
}
|
||||
var moleculeName: String { Self.identifier }
|
||||
|
||||
static var categoryName: String {
|
||||
return "\(MoleculeModelProtocol.self)"
|
||||
}
|
||||
static var categoryName: String { "\(MoleculeModelProtocol.self)" }
|
||||
|
||||
static var categoryCodingKey: String {
|
||||
return "moleculeName"
|
||||
}
|
||||
static var categoryCodingKey: String { "moleculeName" }
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
public typealias BarButtonAction = (BarButtonItem) -> ()
|
||||
|
||||
|
||||
@objc class ActionDelegate: NSObject {
|
||||
var buttonAction: BarButtonAction?
|
||||
@objc func callActionBlock(_ sender: BarButtonItem) {
|
||||
@ -16,7 +17,6 @@ public typealias BarButtonAction = (BarButtonItem) -> ()
|
||||
}
|
||||
|
||||
@objcMembers open class BarButtonItem: UIBarButtonItem, MFButtonProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate
|
||||
//--------------------------------------------------
|
||||
@ -43,4 +43,3 @@ public typealias BarButtonAction = (BarButtonItem) -> ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
public typealias ButtonAction = (Button) -> ()
|
||||
|
||||
|
||||
@objcMembers open class Button: UIButton, MFButtonProtocol, MoleculeViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
@ -65,7 +66,7 @@ public typealias ButtonAction = (Button) -> ()
|
||||
/// Adds a block to be performed for the given event.
|
||||
open func addActionBlock(event: Event, _ buttonBlock: @escaping ButtonAction) {
|
||||
self.buttonAction = buttonBlock
|
||||
addTarget(self, action: #selector(callActionBlock(_:)), for: event)
|
||||
addTarget(self, action: #selector(callActionBlock), for: event)
|
||||
}
|
||||
|
||||
@objc func callActionBlock(_ sender: Button) {
|
||||
@ -103,6 +104,10 @@ public typealias ButtonAction = (Button) -> ()
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
|
||||
if let model = model as? EnableableModelProtocol {
|
||||
isEnabled = model.enabled
|
||||
}
|
||||
@ -119,25 +124,23 @@ public typealias ButtonAction = (Button) -> ()
|
||||
// MARK: Overridables
|
||||
// Base classes need to implement these functions otherwise swift won't respect the subclass functions and use the ones in the protocol extension instead.
|
||||
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
return model.moleculeName
|
||||
model.moleculeName
|
||||
}
|
||||
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil }
|
||||
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
return nil
|
||||
}
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { nil }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Accessibility
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func accessibilityActivate() -> Bool {
|
||||
guard isEnabled else { return false }
|
||||
buttonAction?(self)
|
||||
return buttonAction != nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
@ -160,6 +163,6 @@ extension Button: MVMCoreViewProtocol {
|
||||
extension Button: AppleGuidelinesProtocol {
|
||||
|
||||
override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
return Self.acceptablyOutsideBounds(point: point, bounds: bounds)
|
||||
Self.acceptablyOutsideBounds(point: point, bounds: bounds)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,9 +51,14 @@ import UIKit
|
||||
// MARK:- MoleculeViewProtocol
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
self.model = model
|
||||
|
||||
if let backgroundColor = model.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
@ -63,22 +68,18 @@ import UIKit
|
||||
// MARK: Overridables
|
||||
// Base classes need to implement these functions otherwise swift won't respect the subclass functions and use the ones in the protocol extension instead.
|
||||
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
return model.moleculeName
|
||||
model.moleculeName
|
||||
}
|
||||
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil }
|
||||
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
return nil
|
||||
}
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { nil }
|
||||
}
|
||||
|
||||
// MARK: - AppleGuidelinesProtocol
|
||||
extension Control: AppleGuidelinesProtocol {
|
||||
override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
return Self.acceptablyOutsideBounds(point: point, bounds: bounds)
|
||||
Self.acceptablyOutsideBounds(point: point, bounds: bounds)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -53,33 +53,35 @@ open class ImageView: UIImageView, MoleculeViewProtocol {
|
||||
}
|
||||
|
||||
public func reset() {
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
public func setAsMolecule() { }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
self.model = model
|
||||
|
||||
if let backgroundColor = model.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
open class func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
return model?.moleculeName
|
||||
model?.moleculeName
|
||||
}
|
||||
|
||||
open class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
open class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil }
|
||||
|
||||
open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
return nil
|
||||
}
|
||||
open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { nil }
|
||||
}
|
||||
|
||||
// MARK:- MVMCoreViewProtocol
|
||||
@ -94,4 +96,3 @@ extension ImageView: MVMCoreViewProtocol {
|
||||
MVMCoreUIUtility.setMarginsFor(self, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class SectionHeaderFooterView: UITableViewHeaderFooterView, MoleculeViewProtocol {
|
||||
//--------------------------------------------------
|
||||
@ -43,10 +42,16 @@ import Foundation
|
||||
//--------------------------------------------------
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
self.model = model
|
||||
|
||||
if let backgroundColor = model.backgroundColor {
|
||||
contentView.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
@ -56,16 +61,12 @@ import Foundation
|
||||
// MARK: Overridables
|
||||
// Base classes need to implement these functions otherwise swift won't respect the subclass functions and use the ones in the protocol extension instead.
|
||||
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
return model.moleculeName
|
||||
model.moleculeName
|
||||
}
|
||||
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil }
|
||||
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
return nil
|
||||
}
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { nil }
|
||||
}
|
||||
|
||||
// MARK:- MVMCoreViewProtocol
|
||||
|
||||
@ -11,7 +11,7 @@ import Foundation
|
||||
@objcMembers open class TableView: UITableView {
|
||||
|
||||
/// A block that gets called on tableview frame changes
|
||||
public var frameChangeAction: (() -> Void)?
|
||||
public var frameChangeAction: (() -> ())?
|
||||
|
||||
private var previousFrame = CGRect.zero
|
||||
|
||||
|
||||
@ -93,6 +93,10 @@ extension TextField: MoleculeViewProtocol {
|
||||
if let color = model.backgroundColor?.uiColor {
|
||||
backgroundColor = color
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
|
||||
@ -106,8 +106,8 @@ import UIKit
|
||||
|
||||
open func reset() {
|
||||
|
||||
fontStyle = Styler.Font.RegularBodyLarge
|
||||
placeholderFontStyle = Styler.Font.RegularMicro
|
||||
fontStyle = .RegularBodyLarge
|
||||
placeholderFontStyle = .RegularMicro
|
||||
placeholderTextColor = .mvmCoolGray3
|
||||
textColor = .mvmBlack
|
||||
isEnabled = true
|
||||
|
||||
@ -58,6 +58,10 @@ import UIKit
|
||||
if let backgroundColor = model.backgroundColor {
|
||||
self.backgroundColor = backgroundColor.uiColor
|
||||
}
|
||||
|
||||
if let accessibilityIdentifier = model.accessibilityIdentifier {
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
@ -67,16 +71,12 @@ import UIKit
|
||||
// MARK: Overridables
|
||||
// Base classes need to implement these functions otherwise swift won't respect the subclass functions and use the ones in the protocol extension instead.
|
||||
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
return model.moleculeName
|
||||
model.moleculeName
|
||||
}
|
||||
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil }
|
||||
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
return nil
|
||||
}
|
||||
open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { nil }
|
||||
}
|
||||
|
||||
// MARK:- MVMCoreViewProtocol
|
||||
|
||||
@ -74,7 +74,7 @@ import UIKit
|
||||
}
|
||||
|
||||
open func modulesToListenFor() -> [String]? {
|
||||
loadObject?.requestParameters?.modules as? [String]
|
||||
loadObject?.requestParameters?.allModules()
|
||||
}
|
||||
|
||||
@objc open func responseJSONUpdated(notification: Notification) {
|
||||
|
||||
@ -10,23 +10,22 @@ import Foundation
|
||||
|
||||
public protocol PageBehaviorProtocol: ModelProtocol {
|
||||
|
||||
// The type of rule
|
||||
/// The type of rule
|
||||
var behaviorName: String { get }
|
||||
|
||||
}
|
||||
|
||||
public extension PageBehaviorProtocol {
|
||||
|
||||
var behaviorName: String {
|
||||
get { return Self.identifier }
|
||||
get { Self.identifier }
|
||||
}
|
||||
|
||||
static var categoryCodingKey: String {
|
||||
return "behaviorName"
|
||||
"behaviorName"
|
||||
}
|
||||
|
||||
static var categoryName: String {
|
||||
return "\(PageBehaviorProtocol.self)"
|
||||
"\(PageBehaviorProtocol.self)"
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +33,6 @@ public protocol PageVisibilityBehavior: PageBehaviorProtocol {
|
||||
|
||||
func onPageShown()
|
||||
func onPageHidden()
|
||||
|
||||
}
|
||||
|
||||
public protocol PageScrolledBehavior: PageBehaviorProtocol {
|
||||
@ -45,5 +43,4 @@ public protocol PageScrolledBehavior: PageBehaviorProtocol {
|
||||
public protocol PageBehaviorsTemplateProtocol {
|
||||
|
||||
var behaviors: [PageBehaviorProtocol]? { get set }
|
||||
|
||||
}
|
||||
|
||||
@ -75,11 +75,12 @@ import MVMCore
|
||||
|
||||
/// Convenience function. Gets the form validator from the holder and asks it to validate.
|
||||
public static func validate(delegate: FormHolderProtocol?) -> Bool? {
|
||||
return delegate?.formValidator?.validate()
|
||||
delegate?.formValidator?.validate()
|
||||
}
|
||||
|
||||
/// Validates all rule groups. Returns if valid
|
||||
public func validate() -> Bool {
|
||||
|
||||
var valid = true
|
||||
guard let formRules = formRules else { return valid }
|
||||
|
||||
@ -109,9 +110,10 @@ import MVMCore
|
||||
}
|
||||
}
|
||||
|
||||
// mark Form params
|
||||
// MARK: Form params
|
||||
// TODO: Temporary hacks, rewrite architecture to support this.
|
||||
@objc public extension FormValidator {
|
||||
|
||||
@objc func addFormParams(requestParameters: MVMCoreRequestParameters) {
|
||||
let groupName = getGroupName(forPageType: requestParameters.pageType) ?? FormValidator.defaultGroupName
|
||||
let formParams = self.getFormParams(forGroup: groupName)
|
||||
@ -119,6 +121,7 @@ import MVMCore
|
||||
}
|
||||
|
||||
@objc func getFormParams( forGroup groupName: String) -> [String: Any] {
|
||||
|
||||
var extraParam: [String: Any] = [:]
|
||||
for (fieldKey, field) in fields {
|
||||
if let formFieldValue = field.formFieldValue(),
|
||||
@ -126,6 +129,7 @@ import MVMCore
|
||||
extraParam[fieldKey] = formFieldValue
|
||||
}
|
||||
}
|
||||
|
||||
return extraParam
|
||||
}
|
||||
}
|
||||
@ -145,4 +149,3 @@ public extension FormValidator {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,17 +31,11 @@ public protocol RulesProtocol: ModelProtocol {
|
||||
|
||||
public extension RulesProtocol {
|
||||
|
||||
var type: String {
|
||||
get { return Self.identifier }
|
||||
}
|
||||
var type: String { Self.identifier }
|
||||
|
||||
static var categoryCodingKey: String {
|
||||
return "type"
|
||||
}
|
||||
static var categoryCodingKey: String { "type" }
|
||||
|
||||
static var categoryName: String {
|
||||
return "\(RulesProtocol.self)"
|
||||
}
|
||||
static var categoryName: String { "\(RulesProtocol.self)" }
|
||||
|
||||
// Individual rule can override the function to validate based on the rule type.
|
||||
func validate(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool {
|
||||
|
||||
@ -211,7 +211,7 @@
|
||||
|
||||
if (topMessage && (!self.onlyShowTopMessageWhenCollapsed || !self.expanded)) {
|
||||
self.shortViewHeight.active = NO;
|
||||
} else if (!topMessage && self.onlyShowTopMessageWhenCollapsed && self.expanded) {
|
||||
} else if (!topMessage || (self.onlyShowTopMessageWhenCollapsed && self.expanded)) {
|
||||
self.shortViewHeight.active = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
@ -113,8 +113,8 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
|
||||
- (void)pinATopViewController:(UIViewController *)viewController {
|
||||
self.statusBarHeightConstraint.active = NO;
|
||||
id topGuide = viewController.topLayoutGuide;
|
||||
self.statusBarBottomConstraint = [NSLayoutConstraint constraintWithItem:self.statusBarView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:topGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
|
||||
id topGuide = viewController.view.safeAreaLayoutGuide;
|
||||
self.statusBarBottomConstraint = [NSLayoutConstraint constraintWithItem:self.statusBarView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:topGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
|
||||
self.statusBarBottomConstraint.active = YES;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user