Merge branch 'feature/toolbar_entry_field' into 'release/7_6_0'
Toolbar entry field See merge request BPHV_MIPS/mvm_core_ui!376
This commit is contained in:
commit
07d19f6a2c
@ -94,6 +94,7 @@
|
|||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
||||||
0A7ECC5D243CE85300C828E8 /* DoughnutChartItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */; };
|
0A7ECC5D243CE85300C828E8 /* DoughnutChartItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */; };
|
||||||
0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */; };
|
0A7ECC5F243CEB1200C828E8 /* ColorViewWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */; };
|
||||||
|
0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */; };
|
||||||
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */; };
|
0A7EF85B23D8A52800B2AAD1 /* EntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */; };
|
||||||
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; };
|
0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */; };
|
||||||
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; };
|
0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */; };
|
||||||
@ -102,6 +103,8 @@
|
|||||||
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; };
|
0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; };
|
||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; };
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; };
|
||||||
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
|
||||||
|
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */; };
|
||||||
|
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; };
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
|
||||||
@ -518,6 +521,7 @@
|
|||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxLabel.swift; sourceTree = "<group>"; };
|
0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxLabel.swift; sourceTree = "<group>"; };
|
||||||
0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoughnutChartItemModel.swift; sourceTree = "<group>"; };
|
0A7ECC5C243CE85300C828E8 /* DoughnutChartItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoughnutChartItemModel.swift; sourceTree = "<group>"; };
|
||||||
0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorViewWithLabel.swift; sourceTree = "<group>"; };
|
0A7ECC5E243CEB1200C828E8 /* ColorViewWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorViewWithLabel.swift; sourceTree = "<group>"; };
|
||||||
|
0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIToolbar+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85A23D8A52800B2AAD1 /* EntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85C23D8A95600B2AAD1 /* TextEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = "<group>"; };
|
0A7EF85E23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnEntryFieldModel.swift; sourceTree = "<group>"; };
|
||||||
@ -528,6 +532,8 @@
|
|||||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
||||||
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
|
||||||
|
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDatePicker+Extension.swift"; sourceTree = "<group>"; };
|
||||||
|
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPickerView+Extension.swift"; sourceTree = "<group>"; };
|
||||||
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
|
||||||
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||||
@ -1114,6 +1120,9 @@
|
|||||||
D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */,
|
D21EE53B23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift */,
|
||||||
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */,
|
D202AFE5242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift */,
|
||||||
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */,
|
013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */,
|
||||||
|
0A7ECC6F2441001C00C828E8 /* UIToolbar+Extension.swift */,
|
||||||
|
0AB764D024460F6300E7FE72 /* UIDatePicker+Extension.swift */,
|
||||||
|
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2184,6 +2193,7 @@
|
|||||||
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
|
BB47A586241615EF002BB23C /* ListOneColumnFullWidthTextDividerSubsectionModel.swift in Sources */,
|
||||||
D2B18B812360945C00A9AEDC /* View.swift in Sources */,
|
D2B18B812360945C00A9AEDC /* View.swift in Sources */,
|
||||||
C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */,
|
C6FA7D5423C77A4A00A3614A /* NumberedList.swift in Sources */,
|
||||||
|
0A7ECC702441001C00C828E8 /* UIToolbar+Extension.swift in Sources */,
|
||||||
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
|
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
|
||||||
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
525019E52406852100EED91C /* ListFourColumnDataUsageDividerModel.swift in Sources */,
|
||||||
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */,
|
||||||
@ -2284,6 +2294,7 @@
|
|||||||
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
||||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
||||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||||
|
0AB764D124460F6300E7FE72 /* UIDatePicker+Extension.swift in Sources */,
|
||||||
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
||||||
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
|
D2C78CD224228BBD00B69FDE /* ActionOpenPanelModel.swift in Sources */,
|
||||||
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */,
|
||||||
@ -2364,6 +2375,7 @@
|
|||||||
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
|
||||||
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
|
||||||
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */,
|
||||||
|
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */,
|
||||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||||
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */,
|
||||||
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
|
011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */,
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol {
|
@objcMembers public class ActionCollapseNotificationModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "collapseNotification"
|
public static var identifier: String = "collapseNotification"
|
||||||
public var actionType: String
|
public var actionType: String
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "topAlert"
|
public static var identifier: String = "topAlert"
|
||||||
public var actionType: String = ActionTopAlertModel.identifier
|
public var actionType: String = ActionTopAlertModel.identifier
|
||||||
public var pageType: String
|
public var pageType: String
|
||||||
|
|||||||
@ -69,7 +69,7 @@ import UIKit
|
|||||||
textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6)
|
textFieldTrailingConstraint = dropDownCaretView.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true
|
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: Padding.Four).isActive = true
|
||||||
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,10 +31,9 @@ import UIKit
|
|||||||
return formatter
|
return formatter
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
/// Update the property value to alter the format of how the date is presented.
|
||||||
public var dateFormat: String = "MMM d, y" {
|
public var dateFormat: String = "MMM d, y" {
|
||||||
didSet {
|
didSet { dateFormatter.dateFormat = dateFormat }
|
||||||
dateFormatter.dateFormat = dateFormat
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -69,10 +68,10 @@ import UIKit
|
|||||||
public override func setupFieldContainerContent(_ container: UIView) {
|
public override func setupFieldContainerContent(_ container: UIView) {
|
||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField)
|
datePicker = UIDatePicker.addDatePicker(to: textField)
|
||||||
datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
|
datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
|
||||||
datePicker?.timeZone = NSTimeZone.system
|
datePicker?.timeZone = NSTimeZone.system
|
||||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: self)
|
UIToolbar.addDismissToolbar(to: textField, delegate: self, action: #selector(dismissFieldInput))
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setDatePickerDuration(from startDate: Date?, to endDate: Date?, showStartDate: Bool = true) {
|
@objc public func setDatePickerDuration(from startDate: Date?, to endDate: Date?, showStartDate: Bool = true) {
|
||||||
@ -104,7 +103,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override func dismissFieldInput(_ sender: Any?) {
|
@objc public override func dismissFieldInput(_ sender: Any?) {
|
||||||
|
|
||||||
setTextWith(date: datePicker?.date)
|
setTextWith(date: datePicker?.date)
|
||||||
super.dismissFieldInput(sender)
|
super.dismissFieldInput(sender)
|
||||||
|
|||||||
@ -22,24 +22,25 @@
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case dateFormat
|
case dateFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) ?? "MMM d, y"
|
|
||||||
|
if let dateFormat = try typeContainer.decodeIfPresent(String.self, forKey: .dateFormat) {
|
||||||
|
self.dateFormat = dateFormat
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(dateFormat, forKey: .dateFormat)
|
try container.encode(dateFormat, forKey: .dateFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,7 +211,9 @@ import UIKit
|
|||||||
|
|
||||||
let digitBox = DigitBox()
|
let digitBox = DigitBox()
|
||||||
digitBox.isAccessibilityElement = true
|
digitBox.isAccessibilityElement = true
|
||||||
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: self)
|
let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self
|
||||||
|
digitBox.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
digitBox.digitField.delegate = self
|
digitBox.digitField.delegate = self
|
||||||
digitBox.digitBoxDelegate = self
|
digitBox.digitBoxDelegate = self
|
||||||
return digitBox
|
return digitBox
|
||||||
@ -246,15 +248,6 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public override func defaultValidationBlock() {
|
|
||||||
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let enteredValue = enteredValue else { return false }
|
|
||||||
|
|
||||||
return enteredValue.count > 0 && enteredValue.count == self.digitBoxes.count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||||
|
|
||||||
var selectPreviousField = false
|
var selectPreviousField = false
|
||||||
@ -322,7 +315,7 @@ import UIKit
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc override func dismissFieldInput(_ sender: Any?) {
|
@objc public override func dismissFieldInput(_ sender: Any?) {
|
||||||
|
|
||||||
digitBoxes.forEach {
|
digitBoxes.forEach {
|
||||||
if $0.isSelected {
|
if $0.isSelected {
|
||||||
@ -337,10 +330,16 @@ import UIKit
|
|||||||
guard let model = model as? DigitEntryFieldModel else { return }
|
guard let model = model as? DigitEntryFieldModel else { return }
|
||||||
|
|
||||||
numberOfDigits = model.digits
|
numberOfDigits = model.digits
|
||||||
setAsSecureTextEntry(model.secureEntry)
|
|
||||||
|
|
||||||
for digitBox in digitBoxes {
|
if let entryType = model.type {
|
||||||
digitBox.digitField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: delegateObject?.observingTextFieldDelegate ?? self)
|
setAsSecureTextEntry(entryType == .secure || entryType == .password)
|
||||||
|
}
|
||||||
|
|
||||||
|
let observingDelegate = delegateObject?.observingTextFieldDelegate ?? self
|
||||||
|
|
||||||
|
digitBoxes.forEach {
|
||||||
|
$0.digitField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
}
|
}
|
||||||
|
|
||||||
super.set(with: model, delegateObject, additionalData)
|
super.set(with: model, delegateObject, additionalData)
|
||||||
|
|||||||
@ -17,34 +17,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var digits: Int = 4
|
public var digits: Int = 4
|
||||||
public var secureEntry: Bool = false
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case digits
|
case digits
|
||||||
case secureEntry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) ?? 4
|
|
||||||
secureEntry = try typeContainer.decodeIfPresent(Bool.self, forKey: .secureEntry) ?? false
|
if let digits = try typeContainer.decodeIfPresent(Int.self, forKey: .digits) {
|
||||||
|
self.digits = digits
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(digits, forKey: .digits)
|
try container.encode(digits, forKey: .digits)
|
||||||
try container.encode(secureEntry, forKey: .secureEntry)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import UIKit
|
|||||||
|
|
||||||
public private(set) var titleLabel: Label = {
|
public private(set) var titleLabel: Label = {
|
||||||
let label = Label()
|
let label = Label()
|
||||||
label.font = MFStyler.fontRegularMicro()
|
label.font = Styler.Font.RegularMicro.getFont()
|
||||||
label.textColor = .mvmBlack
|
label.textColor = .mvmBlack
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
@ -31,7 +31,7 @@ import UIKit
|
|||||||
/// Provides contextual information on the TextField.
|
/// Provides contextual information on the TextField.
|
||||||
public private(set) var feedbackLabel: Label = {
|
public private(set) var feedbackLabel: Label = {
|
||||||
let label = Label()
|
let label = Label()
|
||||||
label.font = MFStyler.fontRegularMicro()
|
label.font = Styler.Font.RegularMicro.getFont()
|
||||||
label.textColor = .mvmBlack
|
label.textColor = .mvmBlack
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
@ -48,14 +48,6 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var isValid: Bool = false
|
public var isValid: Bool = false
|
||||||
public var errorMessage: String?
|
|
||||||
public var standardMessage: String? {
|
|
||||||
didSet {
|
|
||||||
if !showError {
|
|
||||||
feedback = standardMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Computed Properties
|
// MARK: - Computed Properties
|
||||||
@ -75,7 +67,7 @@ import UIKit
|
|||||||
public var showError: Bool {
|
public var showError: Bool {
|
||||||
get { return entryFieldContainer.showError }
|
get { return entryFieldContainer.showError }
|
||||||
set (error) {
|
set (error) {
|
||||||
self.feedback = error ? self.errorMessage : self.standardMessage
|
self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback
|
||||||
self.entryFieldContainer.showError = error
|
self.entryFieldContainer.showError = error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +113,10 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var entryFieldModel: EntryFieldModel? {
|
||||||
|
return model as? EntryFieldModel
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Constraints
|
// MARK: - Constraints
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -174,8 +170,6 @@ import UIKit
|
|||||||
@objc final public override func setupView() {
|
@objc final public override func setupView() {
|
||||||
super.setupView()
|
super.setupView()
|
||||||
|
|
||||||
guard subviews.isEmpty else { return }
|
|
||||||
|
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
setContentCompressionResistancePriority(.required, for: .vertical)
|
setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
accessibilityElements = [titleLabel, feedbackLabel]
|
accessibilityElements = [titleLabel, feedbackLabel]
|
||||||
@ -193,7 +187,7 @@ import UIKit
|
|||||||
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
setupFieldContainerContent(entryFieldContainer)
|
setupFieldContainerContent(entryFieldContainer)
|
||||||
|
|
||||||
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4)
|
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: Padding.One)
|
||||||
titleContainerDistance?.isActive = true
|
titleContainerDistance?.isActive = true
|
||||||
entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
||||||
entryFieldContainerLeading?.isActive = true
|
entryFieldContainerLeading?.isActive = true
|
||||||
@ -202,7 +196,7 @@ import UIKit
|
|||||||
|
|
||||||
addSubview(feedbackLabel)
|
addSubview(feedbackLabel)
|
||||||
|
|
||||||
feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: PaddingOne)
|
feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: Padding.Two)
|
||||||
feedbackContainerDistance?.isActive = true
|
feedbackContainerDistance?.isActive = true
|
||||||
feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
||||||
feedbackLabelLeading?.isActive = true
|
feedbackLabelLeading?.isActive = true
|
||||||
@ -217,11 +211,11 @@ import UIKit
|
|||||||
entryFieldContainer.refreshUI()
|
entryFieldContainer.refreshUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Method to override.
|
/**
|
||||||
/// Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
Method to override.
|
||||||
@objc open func setupFieldContainerContent(_ container: UIView) {
|
Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
||||||
// To be overridden by subclass.
|
*/
|
||||||
}
|
@objc open func setupFieldContainerContent(_ container: UIView) { }
|
||||||
|
|
||||||
@objc open override func updateView(_ size: CGFloat) {
|
@objc open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
@ -240,10 +234,11 @@ import UIKit
|
|||||||
|
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
titleLabel.font = MFStyler.fontRegularMicro()
|
titleLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
titleLabel.textColor = .mvmBlack
|
titleLabel.textColor = .mvmBlack
|
||||||
feedbackLabel.font = MFStyler.fontRegularMicro()
|
feedbackLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
feedbackLabel.textColor = .mvmBlack
|
feedbackLabel.textColor = .mvmBlack
|
||||||
|
feedbackLabel.text = nil
|
||||||
entryFieldContainer.reset()
|
entryFieldContainer.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +252,6 @@ import UIKit
|
|||||||
|
|
||||||
title = model.title
|
title = model.title
|
||||||
feedback = model.feedback
|
feedback = model.feedback
|
||||||
errorMessage = model.errorMessage
|
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled
|
||||||
|
|
||||||
if let isLocked = model.locked {
|
if let isLocked = model.locked {
|
||||||
|
|||||||
@ -22,28 +22,21 @@ import Foundation
|
|||||||
public var backgroundColor: Color?
|
public var backgroundColor: Color?
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var feedback: String?
|
public var feedback: String?
|
||||||
public var errorMessage: String = ""
|
public var errorMessage: String?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
public var locked: Bool?
|
public var locked: Bool?
|
||||||
public var selected: Bool?
|
public var selected: Bool?
|
||||||
public var text: String?
|
public var text: String?
|
||||||
|
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
|
|
||||||
public var isValid: Bool? {
|
public var isValid: Bool? {
|
||||||
didSet {
|
didSet { updateUI?() }
|
||||||
updateUI?()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Temporary binding mechanism for the view to update on enable changes.
|
/// Temporary binding mechanism for the view to update on enable changes.
|
||||||
public var updateUI: (() -> Void)?
|
public var updateUI: (() -> ())?
|
||||||
|
|
||||||
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
|
||||||
self.isValid = valid
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
@ -63,10 +56,18 @@ import Foundation
|
|||||||
case groupName
|
case groupName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Validation Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func formFieldValue() -> AnyHashable? {
|
public func formFieldValue() -> AnyHashable? {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
||||||
|
self.isValid = valid
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -76,17 +77,20 @@ import Foundation
|
|||||||
baseValue = text
|
baseValue = text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
title = try typeContainer.decodeIfPresent(String.self, forKey: .title)
|
||||||
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback)
|
||||||
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) ?? ""
|
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
|
||||||
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
||||||
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
||||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||||
|
|
||||||
baseValue = text
|
baseValue = text
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
@ -100,11 +104,11 @@ import Foundation
|
|||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(title, forKey: .title)
|
try container.encodeIfPresent(title, forKey: .title)
|
||||||
try container.encodeIfPresent(feedback, forKey: .feedback)
|
try container.encodeIfPresent(feedback, forKey: .feedback)
|
||||||
try container.encode(errorMessage, forKey: .errorMessage)
|
|
||||||
try container.encode(enabled, forKey: .enabled)
|
|
||||||
try container.encode(locked, forKey: .locked)
|
|
||||||
try container.encode(selected, forKey: .selected)
|
|
||||||
try container.encodeIfPresent(text, forKey: .text)
|
try container.encodeIfPresent(text, forKey: .text)
|
||||||
|
try container.encodeIfPresent(locked, forKey: .locked)
|
||||||
|
try container.encodeIfPresent(selected, forKey: .selected)
|
||||||
|
try container.encodeIfPresent(errorMessage, forKey: .errorMessage)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)
|
||||||
|
|
||||||
|
|
||||||
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -62,7 +64,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self)
|
pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput))
|
||||||
textField.hideBlinkingCaret = true
|
textField.hideBlinkingCaret = true
|
||||||
textField.autocorrectionType = .no
|
textField.autocorrectionType = .no
|
||||||
uiTextFieldDelegate = self
|
uiTextFieldDelegate = self
|
||||||
|
|||||||
@ -23,7 +23,6 @@
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
|
||||||
case options
|
case options
|
||||||
case selectedIndex
|
case selectedIndex
|
||||||
}
|
}
|
||||||
@ -35,14 +34,17 @@
|
|||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
options = try typeContainer.decode([String].self, forKey: .options)
|
options = try typeContainer.decode([String].self, forKey: .options)
|
||||||
selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) ?? 0
|
|
||||||
|
if let selectedIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .selectedIndex) {
|
||||||
|
self.selectedIndex = selectedIndex
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
|
||||||
try container.encode(options, forKey: .options)
|
try container.encode(options, forKey: .options)
|
||||||
try container.encode(options, forKey: .selectedIndex)
|
try container.encode(options, forKey: .selectedIndex)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,6 +48,18 @@ import MVMCore
|
|||||||
set { text = MVMCoreUIUtility.formatMdn(newValue) }
|
set { text = MVMCoreUIUtility.formatMdn(newValue) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Toggles selected or original (unselected) UI.
|
||||||
|
public override var isSelected: Bool {
|
||||||
|
get { return entryFieldContainer.isSelected }
|
||||||
|
set (selected) {
|
||||||
|
if selected && showError {
|
||||||
|
showError = false
|
||||||
|
}
|
||||||
|
|
||||||
|
super.isSelected = selected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -77,11 +89,14 @@ import MVMCore
|
|||||||
super.setupFieldContainerContent(container)
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
}
|
||||||
|
|
||||||
let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar()
|
open override func setupTextFieldToolbar() {
|
||||||
|
|
||||||
|
let toolbar = UIToolbar.createEmptyToolbar()
|
||||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:)))
|
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts))
|
||||||
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:)))
|
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput))
|
||||||
toolbar.items = [contacts, space, dismissButton]
|
toolbar.items = [contacts, space, dismissButton]
|
||||||
textField.inputAccessoryView = toolbar
|
textField.inputAccessoryView = toolbar
|
||||||
}
|
}
|
||||||
@ -108,13 +123,13 @@ import MVMCore
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
let isValid = hasValidMDN()
|
isValid = hasValidMDN()
|
||||||
|
|
||||||
if isValid {
|
if self.isValid {
|
||||||
showError = false
|
showError = false
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
entryFieldModel?.errorMessage = entryFieldModel?.errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||||
showError = true
|
showError = true
|
||||||
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
UIAccessibility.post(notification: .layoutChanged, argument: textField)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import UIKit
|
|||||||
/// Called when the entered text becomes invalid based on the validation block
|
/// Called when the entered text becomes invalid based on the validation block
|
||||||
@objc optional func isInvalid(textfield: TextEntryField?)
|
@objc optional func isInvalid(textfield: TextEntryField?)
|
||||||
/// Dismisses the keyboard.
|
/// Dismisses the keyboard.
|
||||||
@objc optional func dismissFieldInput(sender: Any?)
|
@objc optional func dismissFieldInput(_ sender: Any?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ import UIKit
|
|||||||
let textField = TextField()
|
let textField = TextField()
|
||||||
textField.isAccessibilityElement = true
|
textField.isAccessibilityElement = true
|
||||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
textField.textColor = .mvmBlack
|
textField.textColor = .mvmBlack
|
||||||
textField.smartQuotesType = .no
|
textField.smartQuotesType = .no
|
||||||
textField.smartDashesType = .no
|
textField.smartDashesType = .no
|
||||||
@ -36,13 +36,19 @@ import UIKit
|
|||||||
return textField
|
return textField
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public lazy var errorImage: UIImageView = {
|
||||||
|
let image = MVMCoreUIUtility.imageNamed("alert_standard")
|
||||||
|
let imageView = UIImageView(image: image)
|
||||||
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
imageView.heightAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
imageView.widthAnchor.constraint(equalToConstant: 20).isActive = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Stored Properties
|
// MARK: - Stored Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
/// Set enabled and disabled colors to be utilized when setting this texfield's isEnabled property.
|
|
||||||
public var textColor: (enabled: UIColor?, disabled: UIColor?) = (.mvmBlack, .mvmCoolGray3)
|
|
||||||
|
|
||||||
private var observingForChange: Bool = false
|
private var observingForChange: Bool = false
|
||||||
|
|
||||||
/// Validate on each entry in the textField. Default: true
|
/// Validate on each entry in the textField. Default: true
|
||||||
@ -68,7 +74,7 @@ import UIKit
|
|||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
self.textField.isEnabled = enabled
|
self.textField.isEnabled = enabled
|
||||||
self.textField.textColor = enabled ? self.textColor.enabled : self.textColor.disabled
|
self.textField.textColor = enabled ? self.textEntryFieldModel?.enabledTextColor.uiColor : self.textEntryFieldModel?.disabledTextColor.uiColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,11 +84,15 @@ import UIKit
|
|||||||
set (error) {
|
set (error) {
|
||||||
|
|
||||||
if error {
|
if error {
|
||||||
textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", errorMessage ?? "")
|
textField.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField.text ?? "", entryFieldModel?.errorMessage ?? "")
|
||||||
} else {
|
} else {
|
||||||
textField.accessibilityValue = nil
|
textField.accessibilityValue = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if textField.isSecureTextEntry {
|
||||||
|
showErrorView(error)
|
||||||
|
}
|
||||||
|
|
||||||
super.showError = error
|
super.showError = error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,12 +112,6 @@ import UIKit
|
|||||||
set { textField.placeholder = newValue }
|
set { textField.placeholder = newValue }
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Property Observers
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public var validationBlock: ((_ value: String?) -> Bool)?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate Properties
|
// MARK: - Delegate Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -169,21 +173,21 @@ import UIKit
|
|||||||
|
|
||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
container.addSubview(textField)
|
container.addSubview(textField)
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
textField.heightAnchor.constraint(equalToConstant: 24),
|
textField.heightAnchor.constraint(equalToConstant: Padding.Five),
|
||||||
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 12),
|
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: Padding.Three),
|
||||||
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
|
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: Padding.Three),
|
||||||
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 12)
|
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: Padding.Three)
|
||||||
])
|
])
|
||||||
|
|
||||||
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 16)
|
textFieldTrailingConstraint = container.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Three)
|
||||||
textFieldTrailingConstraint?.isActive = true
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
textField.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||||
textField.addTarget(self, action: #selector(dismissFieldInput(_:)), for: .editingDidEnd)
|
textField.addTarget(self, action: #selector(dismissFieldInput), for: .editingDidEnd)
|
||||||
|
|
||||||
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||||
entryFieldContainer.addGestureRecognizer(tap)
|
entryFieldContainer.addGestureRecognizer(tap)
|
||||||
@ -194,18 +198,14 @@ import UIKit
|
|||||||
@objc open override func updateView(_ size: CGFloat) {
|
@objc open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
layoutIfNeeded()
|
layoutIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
textField.font = MFStyler.fontRegularBodyLarge()
|
textField.font = Styler.Font.RegularBodyLarge.getFont()
|
||||||
}
|
|
||||||
|
|
||||||
@objc deinit {
|
|
||||||
setBothTextDelegates(to: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||||
@ -213,18 +213,16 @@ import UIKit
|
|||||||
uiTextFieldDelegate = delegate
|
uiTextFieldDelegate = delegate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open func setupTextFieldToolbar() {
|
||||||
|
let observingDelegate = observingTextFieldDelegate ?? self
|
||||||
|
textField.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||||
|
action: #selector(observingDelegate.dismissFieldInput))
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Observing for Change (TextFieldDelegate)
|
// MARK: - Observing for Change (TextFieldDelegate)
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public func defaultValidationBlock() {
|
|
||||||
|
|
||||||
validationBlock = { enteredValue in
|
|
||||||
guard let enteredValue = enteredValue else { return false }
|
|
||||||
return enteredValue.count > 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
@objc override open func resignFirstResponder() -> Bool {
|
@objc override open func resignFirstResponder() -> Bool {
|
||||||
if validateWhenDoneEditing {
|
if validateWhenDoneEditing {
|
||||||
@ -276,10 +274,30 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func dismissFieldInput(_ sender: Any?) {
|
@objc public func dismissFieldInput(_ sender: Any?) {
|
||||||
resignFirstResponder()
|
resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func showErrorView(_ show: Bool) {
|
||||||
|
|
||||||
|
if show {
|
||||||
|
entryFieldContainer.addSubview(errorImage)
|
||||||
|
|
||||||
|
textFieldTrailingConstraint?.isActive = false
|
||||||
|
textFieldTrailingConstraint = errorImage.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two)
|
||||||
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
|
||||||
|
entryFieldContainer.trailingAnchor.constraint(equalTo: errorImage.trailingAnchor, constant: Padding.Three).isActive = true
|
||||||
|
errorImage.centerYAnchor.constraint(equalTo: entryFieldContainer.centerYAnchor).isActive = true
|
||||||
|
|
||||||
|
} else {
|
||||||
|
errorImage.removeFromSuperview()
|
||||||
|
textFieldTrailingConstraint?.isActive = false
|
||||||
|
textFieldTrailingConstraint = entryFieldContainer.trailingAnchor.constraint(equalTo: textField.trailingAnchor, constant: Padding.Two)
|
||||||
|
textFieldTrailingConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MoleculeViewProtocol
|
// MARK: - MoleculeViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -291,34 +309,36 @@ import UIKit
|
|||||||
|
|
||||||
model.updateUI = { [weak self] in
|
model.updateUI = { [weak self] in
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
if self?.isSelected ?? false {
|
guard let self = self else { return }
|
||||||
self?.updateValidation(model.isValid ?? true)
|
|
||||||
|
if self.isSelected {
|
||||||
|
self.updateValidation(model.isValid ?? true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||||
textColor.enabled = model.enabledTextColor?.uiColor
|
|
||||||
textColor.disabled = model.disabledTextColor?.uiColor
|
|
||||||
text = model.text
|
text = model.text
|
||||||
placeholder = model.placeholder
|
placeholder = model.placeholder
|
||||||
|
|
||||||
switch model.type {
|
switch model.type {
|
||||||
case .password:
|
case .password, .secure:
|
||||||
textField.isSecureTextEntry = true
|
textField.isSecureTextEntry = true
|
||||||
|
|
||||||
case .number:
|
case .number:
|
||||||
textField.keyboardType = .numberPad
|
textField.keyboardType = .numberPad
|
||||||
|
|
||||||
case .email:
|
case .email:
|
||||||
textField.keyboardType = .emailAddress
|
textField.keyboardType = .emailAddress
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultValidationBlock()
|
|
||||||
|
|
||||||
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate
|
||||||
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate
|
||||||
textField.inputAccessoryView = MVMCoreUICommonViewsUtility.getToolbarWithDoneButton(delegate: observingTextFieldDelegate ?? self)
|
setupTextFieldToolbar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,9 +8,13 @@
|
|||||||
|
|
||||||
|
|
||||||
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
@objcMembers public class TextEntryFieldModel: EntryFieldModel {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Types
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
public enum EntryType: String, Codable {
|
public enum EntryType: String, Codable {
|
||||||
case password
|
case password
|
||||||
|
case secure
|
||||||
case number
|
case number
|
||||||
case email
|
case email
|
||||||
}
|
}
|
||||||
@ -24,8 +28,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var placeholder: String?
|
public var placeholder: String?
|
||||||
public var enabledTextColor: Color?
|
public var enabledTextColor: Color = Color(uiColor: .mvmBlack)
|
||||||
public var disabledTextColor: Color?
|
public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||||
public var type: EntryType?
|
public var type: EntryType?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -34,7 +38,6 @@
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case text
|
|
||||||
case placeholder
|
case placeholder
|
||||||
case enabledTextColor
|
case enabledTextColor
|
||||||
case disabledTextColor
|
case disabledTextColor
|
||||||
@ -42,27 +45,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
|
||||||
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
||||||
enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor)
|
|
||||||
disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor)
|
|
||||||
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
||||||
|
|
||||||
|
if let enabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .enabledTextColor) {
|
||||||
|
self.enabledTextColor = enabledTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) {
|
||||||
|
self.disabledTextColor = disabledTextColor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func encode(to encoder: Encoder) throws {
|
public override func encode(to encoder: Encoder) throws {
|
||||||
try super.encode(to: encoder)
|
try super.encode(to: encoder)
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeIfPresent(text, forKey: .text)
|
|
||||||
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
||||||
try container.encodeIfPresent(enabledTextColor, forKey: .enabledTextColor)
|
try container.encode(enabledTextColor, forKey: .enabledTextColor)
|
||||||
try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor)
|
try container.encode(disabledTextColor, forKey: .disabledTextColor)
|
||||||
try container.encodeIfPresent(type, forKey: .type)
|
try container.encodeIfPresent(type, forKey: .type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift
Normal file
37
MVMCoreUI/Atomic/Extensions/UIDatePicker+Extension.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// UIDatePicker+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/14/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIDatePicker {
|
||||||
|
|
||||||
|
class func addDatePicker(to textField: UITextField) -> UIDatePicker {
|
||||||
|
|
||||||
|
let datePicker = UIDatePicker()
|
||||||
|
datePicker.backgroundColor = .mvmWhite
|
||||||
|
datePicker.datePickerMode = .date
|
||||||
|
|
||||||
|
let locale = NSLocale.current as NSLocale
|
||||||
|
datePicker.locale = locale as Locale
|
||||||
|
datePicker.calendar = locale.object(forKey: .calendar) as? Calendar
|
||||||
|
textField.inputView = datePicker
|
||||||
|
|
||||||
|
return datePicker
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addTimeAndDatePicker(to textField: UITextField) -> UIDatePicker {
|
||||||
|
|
||||||
|
let datePicker = UIDatePicker()
|
||||||
|
datePicker.backgroundColor = .mvmWhite
|
||||||
|
datePicker.datePickerMode = .time
|
||||||
|
textField.inputView = datePicker
|
||||||
|
|
||||||
|
return datePicker
|
||||||
|
}
|
||||||
|
}
|
||||||
38
MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift
Normal file
38
MVMCoreUI/Atomic/Extensions/UIPickerView+Extension.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// UIPickerView.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/14/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIPickerView {
|
||||||
|
|
||||||
|
class func createPickerView() -> UIPickerView {
|
||||||
|
|
||||||
|
let picker = UIPickerView(frame: .zero)
|
||||||
|
picker.backgroundColor = .mvmWhite
|
||||||
|
picker.showsSelectionIndicator = true
|
||||||
|
return picker
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addPicker(to textField: UITextField, delegate: TextFieldAndPickerDelegate?, dismissAction: Selector?) -> UIPickerView {
|
||||||
|
|
||||||
|
// Sets up the picker (same tag as the textfield)
|
||||||
|
let picker = createPickerView()
|
||||||
|
picker.delegate = delegate
|
||||||
|
picker.dataSource = delegate
|
||||||
|
picker.tag = textField.tag
|
||||||
|
textField.inputView = picker
|
||||||
|
|
||||||
|
// Adds a dismiss toolbar, since all fields with pickers should have one.
|
||||||
|
if let dismissAction = dismissAction {
|
||||||
|
UIToolbar.addDismissToolbar(to: textField, delegate: delegate, action: dismissAction)
|
||||||
|
}
|
||||||
|
|
||||||
|
return picker
|
||||||
|
}
|
||||||
|
}
|
||||||
56
MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift
Normal file
56
MVMCoreUI/Atomic/Extensions/UIToolbar+Extension.swift
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// UIToolbar+Extension.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 4/10/20.
|
||||||
|
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol TextFieldOrView { }
|
||||||
|
|
||||||
|
extension UITextView: TextFieldOrView { }
|
||||||
|
extension UITextField: TextFieldOrView { }
|
||||||
|
|
||||||
|
|
||||||
|
public extension UIToolbar {
|
||||||
|
|
||||||
|
class func createEmptyToolbar() -> UIToolbar {
|
||||||
|
|
||||||
|
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44))
|
||||||
|
toolbar.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleWidth]
|
||||||
|
toolbar.barStyle = .default
|
||||||
|
toolbar.barTintColor = .mvmCoolGray3
|
||||||
|
toolbar.tintColor = .mvmBlack
|
||||||
|
toolbar.isTranslucent = true
|
||||||
|
|
||||||
|
return toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
class func getToolbarWithDoneButton(delegate: Any?, action: Selector) -> UIToolbar {
|
||||||
|
|
||||||
|
let toolbar = createEmptyToolbar()
|
||||||
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
|
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: action)
|
||||||
|
toolbar.setItems([space, button], animated: false)
|
||||||
|
|
||||||
|
return toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
class func addDismissToolbar(to object: TextFieldOrView, delegate: Any?, action: Selector) {
|
||||||
|
|
||||||
|
let toolbar = Self.getToolbarWithDoneButton(delegate: delegate, action: action)
|
||||||
|
|
||||||
|
switch object {
|
||||||
|
case is UITextField:
|
||||||
|
(object as? UITextField)?.inputAccessoryView = toolbar
|
||||||
|
|
||||||
|
case is UITextView:
|
||||||
|
(object as? UITextView)?.inputAccessoryView = toolbar
|
||||||
|
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,7 +36,7 @@ open class ScrollingViewController: ViewController {
|
|||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
// Adds the tap gesture to dismiss the keyboard.
|
// Adds the tap gesture to dismiss the keyboard.
|
||||||
dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput(sender:)))
|
dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput))
|
||||||
view.addGestureRecognizer(dismissKeyboardTapGesture!)
|
view.addGestureRecognizer(dismissKeyboardTapGesture!)
|
||||||
dismissKeyboardTapGesture?.isEnabled = false
|
dismissKeyboardTapGesture?.isEnabled = false
|
||||||
scrollView.alwaysBounceVertical = false
|
scrollView.alwaysBounceVertical = false
|
||||||
|
|||||||
@ -405,7 +405,7 @@ import UIKit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc open func dismissFieldInput(sender: Any?) {
|
@objc open func dismissFieldInput(_ sender: Any?) {
|
||||||
selectedField?.resignFirstResponder()
|
selectedField?.resignFirstResponder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,7 @@ import UIKit
|
|||||||
|
|
||||||
/// Total control over the drawn top, bottom, left and right borders.
|
/// Total control over the drawn top, bottom, left and right borders.
|
||||||
public var disableAllBorders = false {
|
public var disableAllBorders = false {
|
||||||
didSet {
|
didSet { bottomBar?.isHidden = disableAllBorders }
|
||||||
bottomBar?.isHidden = disableAllBorders
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private(set) var fieldState: FieldState = .original {
|
private(set) var fieldState: FieldState = .original {
|
||||||
|
|||||||
@ -10,10 +10,8 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
open class Styler {
|
open class Styler {
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Enums
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
|
// MARK:- Font Enum
|
||||||
public enum Font: String, Codable {
|
public enum Font: String, Codable {
|
||||||
case Title2XLarge
|
case Title2XLarge
|
||||||
case TitleXLarge
|
case TitleXLarge
|
||||||
|
|||||||
23
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json
vendored
Normal file
23
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @1x.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "alert_standard @3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @1x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 279 B |
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png
vendored
Normal file
BIN
MVMCoreUI/SupportingFiles/Media.xcassets/alert_standard.imageset/alert_standard @3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 771 B |
@ -14,7 +14,7 @@ public extension MVMCoreUICommonViewsUtility {
|
|||||||
|
|
||||||
let toolbar = self.makeEmptyToolbar()
|
let toolbar = self.makeEmptyToolbar()
|
||||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||||
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput(sender:)))
|
let button = UIBarButtonItem(barButtonSystemItem: .done, target: delegate, action: #selector(ObservingTextFieldDelegate.dismissFieldInput))
|
||||||
button.tintColor = .black
|
button.tintColor = .black
|
||||||
toolbar.setItems([space, button], animated: false)
|
toolbar.setItems([space, button], animated: false)
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user