This commit is contained in:
Kevin G Christiano 2019-11-21 11:47:12 -05:00
parent 26c73070d9
commit 88442fe59c
13 changed files with 361 additions and 355 deletions

View File

@ -42,10 +42,10 @@
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */; }; 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */; };
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; }; 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; };
0A6BF4722360C56C0028F841 /* DropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* DropdownEntryField.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
0ABD136B237B193A0081388D /* FormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* FormView.swift */; }; 0ABD136B237B193A0081388D /* FormFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* FormFieldContainer.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 */; };
@ -236,12 +236,12 @@
0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryField.swift; sourceTree = "<group>"; }; 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryField.swift; sourceTree = "<group>"; };
0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; }; 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; };
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; }; 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
0A6BF4712360C56C0028F841 /* DropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropdownEntryField.swift; sourceTree = "<group>"; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = "<group>"; };
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; }; 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; }; 0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; };
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
0ABD136A237B193A0081388D /* FormView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormView.swift; sourceTree = "<group>"; }; 0ABD136A237B193A0081388D /* FormFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldContainer.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>"; };
@ -452,7 +452,7 @@
0ABD1369237B18EE0081388D /* views */ = { 0ABD1369237B18EE0081388D /* views */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0ABD136A237B193A0081388D /* FormView.swift */, 0ABD136A237B193A0081388D /* FormFieldContainer.swift */,
); );
path = views; path = views;
sourceTree = "<group>"; sourceTree = "<group>";
@ -809,7 +809,7 @@
0A21DB7E235DECC500C160A2 /* EntryField.swift */, 0A21DB7E235DECC500C160A2 /* EntryField.swift */,
0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */, 0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */,
0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */, 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */,
0A6BF4712360C56C0028F841 /* DropdownEntryField.swift */, 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */,
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */, 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */,
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */,
); );
@ -1187,14 +1187,14 @@
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
0A6BF4722360C56C0028F841 /* DropdownEntryField.swift in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */, 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */,
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */,
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
0ABD136B237B193A0081388D /* FormView.swift in Sources */, 0ABD136B237B193A0081388D /* FormFieldContainer.swift in Sources */,
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */,
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,

View File

@ -1,5 +1,5 @@
// //
// DropdownEntryField.swift // BaseDropdownEntryField.swift
// MVMCoreUI // MVMCoreUI
// //
// Created by Kevin Christiano on 10/23/19. // Created by Kevin Christiano on 10/23/19.
@ -9,10 +9,10 @@
import UIKit import UIKit
/** /**
This class is intended to be subclassed. This class is intended to be subclassed.
See ItemDropdownEntryField and DateDropdownEntryField. See ItemDropdownEntryField and DateDropdownEntryField.
*/ */
@objcMembers open class DropdownEntryField: TextEntryField { @objcMembers open class BaseDropdownEntryField: TextEntryField {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Outlets // MARK: - Outlets
//-------------------------------------------------- //--------------------------------------------------
@ -31,9 +31,11 @@ import UIKit
// MARK: - Property Observers // MARK: - Property Observers
//-------------------------------------------------- //--------------------------------------------------
public override var isEnabled: Bool { @objc public override var isEnabled: Bool {
didSet { get { super.isEnabled }
dropDownCaretView.isEnabled = isEnabled set (enabled) {
dropDownCaretView.isEnabled = enabled
super.isEnabled = enabled
} }
} }
@ -41,11 +43,11 @@ import UIKit
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public override init(frame: CGRect) { @objc public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
} }
required public init?(coder: NSCoder) { @objc required public init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
fatalError("DropdownEntryField does not support xib.") fatalError("DropdownEntryField does not support xib.")
} }
@ -54,7 +56,7 @@ import UIKit
// MARK: - Setup // MARK: - Setup
//-------------------------------------------------- //--------------------------------------------------
public override func setupFieldContainerContent(_ container: UIView) { @objc public override func setupFieldContainerContent(_ container: UIView) {
super.setupFieldContainerContent(container) super.setupFieldContainerContent(container)
container.addSubview(dropDownCaretView) container.addSubview(dropDownCaretView)
@ -66,7 +68,6 @@ import UIKit
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true
container.bottomAnchor.constraint(greaterThanOrEqualTo: dropDownCaretView.bottomAnchor, constant: 13).isActive = true container.bottomAnchor.constraint(greaterThanOrEqualTo: dropDownCaretView.bottomAnchor, constant: 13).isActive = true
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
let caretTap = UITapGestureRecognizer(target: self, action: #selector(startEditing)) let caretTap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
@ -75,15 +76,13 @@ import UIKit
} }
// MARK: - Molecular // MARK: - Molecular
extension DropdownEntryField { extension BaseDropdownEntryField {
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json, !dictionary.isEmpty else { return } guard let dictionary = json, !dictionary.isEmpty else { return }
if let _ = dictionary[KeyType] as? String { dropDownCaretView.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
dropDownCaretView.isHidden = false
}
} }
} }

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
open class DateDropdownEntryField: DropdownEntryField { @objcMembers open class DateDropdownEntryField: BaseDropdownEntryField {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -32,44 +32,41 @@ open class DateDropdownEntryField: DropdownEntryField {
return formatter return formatter
}() }()
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
private weak var proprietorTextDelegate: UITextFieldDelegate?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
public convenience init() { @objc public override init(frame: CGRect) {
self.init(frame: .zero) super.init(frame: frame)
setup() setup()
} }
public convenience init(startDate: Date, endDate: Date, showStartDate: Bool = true) { @objc public convenience init() {
self.init(frame: .zero)
}
@objc public convenience init(startDate: Date, endDate: Date, showStartDate: Bool = true) {
self.init(frame: .zero) self.init(frame: .zero)
setup()
setDatePickerDuration(from: startDate, to: endDate, showStartDate: showStartDate) setDatePickerDuration(from: startDate, to: endDate, showStartDate: showStartDate)
} }
private func setup() { @objc required public init?(coder: NSCoder) {
fatalError("DateDropdownEntryField init(coder:) has not been implemented")
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
@objc private func setup() {
datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField) datePicker = MVMCoreUICommonViewsUtility.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) MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: self)
uiTextFieldDelegate = self
} }
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
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) {
datePicker?.minimumDate = startDate datePicker?.minimumDate = startDate
datePicker?.maximumDate = endDate datePicker?.maximumDate = endDate
@ -79,7 +76,7 @@ open class DateDropdownEntryField: DropdownEntryField {
} }
} }
public func dismissDatePicker() -> Date? { @objc public func dismissDatePicker() -> Date? {
let pickedDate = datePicker?.date let pickedDate = datePicker?.date
setTextWith(date: pickedDate) setTextWith(date: pickedDate)
@ -88,8 +85,8 @@ open class DateDropdownEntryField: DropdownEntryField {
return pickedDate return pickedDate
} }
private func setTextWith(date: Date?) { @objc private func setTextWith(date: Date?) {
guard let date = date else { return } guard let date = date else { return }
if calendar.isDate(date, inSameDayAs: Date()) { if calendar.isDate(date, inSameDayAs: Date()) {
@ -104,26 +101,16 @@ open class DateDropdownEntryField: DropdownEntryField {
super.dismissFieldInput(sender) super.dismissFieldInput(sender)
} }
@objc func pickerValueChanged(_ sender: UIDatePicker){ @objc func pickerValueChanged(_ sender: UIDatePicker) {
setTextWith(date: datePicker?.date)
}
}
// MARK: - UITextField Intercept
extension DateDropdownEntryField {
public func textFieldDidBeginEditing(_ textField: UITextField) {
isSelected = true setTextWith(date: datePicker?.date)
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
} }
} }
// MARK: - Molecular // MARK: - Molecular
extension DateDropdownEntryField { extension DateDropdownEntryField {
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json, !dictionary.isEmpty else { return } guard let dictionary = json, !dictionary.isEmpty else { return }

View File

@ -8,9 +8,8 @@
import UIKit import UIKit
@objc protocol DigitBoxDelegate: NSObjectProtocol { @objc protocol DigitBoxDelegate {
@objc optional func digitFieldDidDelete(_ textField: UITextField?) @objc optional func digitFieldDidDelete(_ textField: UITextField?)
@objc optional func textFieldDidChange(_ textField: UITextField)
} }
@ -40,11 +39,12 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
public override var showError: Bool { public override var showError: Bool {
didSet { get { return super.showError }
set (error) {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.borderStrokeColor = self.showError ? .mfPumpkin() : .mfSilver() self.borderStrokeColor = error ? .mfPumpkin() : .mfSilver()
let barHeight: CGFloat = self.showError ? 4 : 1 let barHeight: CGFloat = self.showError ? 4 : 1
self.bottomBar?.frame = CGRect(x: 0, y: self.bounds.height - barHeight, width: self.bounds.width, height: barHeight) self.bottomBar?.frame = CGRect(x: 0, y: self.bounds.height - barHeight, width: self.bounds.width, height: barHeight)
@ -53,6 +53,7 @@ import UIKit
self.setNeedsDisplay() self.setNeedsDisplay()
self.layoutIfNeeded() self.layoutIfNeeded()
} }
super.showError = error
} }
} }
@ -142,16 +143,7 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.isBackspace {
digitBoxDelegate?.digitFieldDidDelete?(self.digitField)
}
return true
}
public override func updateView(_ size: CGFloat) { public override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
@ -188,13 +180,3 @@ import UIKit
} }
} }
} }
// TODO: Move if working properly.
extension String {
var isBackspace: Bool {
let char = self.cString(using: String.Encoding.utf8)!
return strcmp(char, "\\b") == -92
}
}

View File

@ -27,14 +27,15 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
public override var isEnabled: Bool { public override var isEnabled: Bool {
didSet { get { return super.isEnabled }
titleLabel.textColor = self.isEnabled ? .mfBattleshipGrey() : .mfSilver() set (enabled) {
titleLabel.textColor = enabled ? .mfBattleshipGrey() : .mfSilver()
digitBoxes.forEach { digitBoxes.forEach {
$0.isEnabled = self.isEnabled $0.isEnabled = enabled
$0.isUserInteractionEnabled = isEnabled $0.isUserInteractionEnabled = enabled
$0.digitField.isEnabled = isEnabled $0.digitField.isEnabled = enabled
$0.digitField.textColor = isEnabled ? .black : .mfBattleshipGrey() $0.digitField.textColor = enabled ? .black : .mfBattleshipGrey()
} }
} }
} }
@ -46,8 +47,9 @@ import UIKit
} }
public override var isLocked: Bool { public override var isLocked: Bool {
didSet { get { return super.isLocked }
digitBoxes.forEach { $0.isLocked = self.isLocked } set (locked) {
digitBoxes.forEach { $0.isLocked = locked }
} }
} }
@ -127,25 +129,20 @@ import UIKit
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public override init(frame: CGRect) { @objc public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
} }
public convenience init() { @objc public convenience init() {
self.init(frame: .zero) self.init(frame: .zero)
} }
public convenience init(numberOfDigits: Int) { @objc public convenience init(numberOfDigits: Int) {
self.init(frame: .zero) self.init(frame: .zero)
self.numberOfDigits = numberOfDigits self.numberOfDigits = numberOfDigits
} }
public init(numberOfDigits: Int, bothDelegates delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?, size: CGFloat? = nil) { @objc required public init?(coder: NSCoder) {
self.numberOfDigits = numberOfDigits
super.init(bothDelegates: delegate)
}
required public init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
fatalError("DigitEntryField xib has not been implemented") fatalError("DigitEntryField xib has not been implemented")
} }
@ -154,15 +151,15 @@ import UIKit
// MARK: - Setup // MARK: - Setup
//-------------------------------------------------- //--------------------------------------------------
public override func setupFieldContainerContent(_ container: UIView) { @objc public override func setupFieldContainerContent(_ container: UIView) {
alignCenterHorizontal() alignCenterHorizontal()
isAccessibilityElement = false isAccessibilityElement = false
entryContainer.disableBorders = true entryContainer.disableAllBorders = true
assembleDigitFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth()) assembleDigitFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
} }
private func createDigitField() -> DigitBox { @objc private func createDigitField() -> DigitBox {
let digitBox = DigitBox() let digitBox = DigitBox()
digitBox.isAccessibilityElement = true digitBox.isAccessibilityElement = true
@ -172,7 +169,7 @@ import UIKit
return digitBox return digitBox
} }
func assembleDigitFieldsView(size: CGFloat) { @objc func assembleDigitFieldsView(size: CGFloat) {
var accessibleElements: [Any] = [titleLabel] var accessibleElements: [Any] = [titleLabel]
@ -218,10 +215,10 @@ import UIKit
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
open override func updateView(_ size: CGFloat) { @objc open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
entryContainer.disableBorders = true entryContainer.disableAllBorders = true
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
@ -234,10 +231,10 @@ import UIKit
} }
} }
open override func reset() { @objc open override func reset() {
super.reset() super.reset()
entryContainer.disableBorders = false entryContainer.disableAllBorders = false
digitBoxes.forEach { $0.reset() } digitBoxes.forEach { $0.reset() }
} }
@ -245,7 +242,7 @@ import UIKit
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
public func setAsSecureTextEntry(_ secureEntry: Bool) { @objc public func setAsSecureTextEntry(_ secureEntry: Bool) {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
@ -259,7 +256,7 @@ import UIKit
} }
} }
public override func defaultValidationBlock() { @objc public override func defaultValidationBlock() {
validationBlock = { enteredValue in validationBlock = { enteredValue in
guard let enteredValue = enteredValue else { return false } guard let enteredValue = enteredValue else { return false }
@ -268,7 +265,7 @@ import UIKit
} }
} }
public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) { @objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
var selectPreviousField = false var selectPreviousField = false
@ -292,7 +289,7 @@ import UIKit
} }
} }
public func selectNextDigitField(_ currentTextField: UITextField?, clear: Bool) { @objc public func selectNextDigitField(_ currentTextField: UITextField?, clear: Bool) {
var selectNextField = false var selectNextField = false
@ -326,7 +323,7 @@ import UIKit
selectedDigitField?.digitField.becomeFirstResponder() selectedDigitField?.digitField.becomeFirstResponder()
} }
override open func resignFirstResponder() -> Bool { @objc override open func resignFirstResponder() -> Bool {
selectedDigitField?.digitField.resignFirstResponder() selectedDigitField?.digitField.resignFirstResponder()
selectedDigitField?.isSelected = false selectedDigitField?.isSelected = false
@ -343,7 +340,7 @@ import UIKit
} }
} }
open class func getEnabledDigitFields(_ textFieldToDetermine: [DigitBox]) -> [TextField]? { @objc open class func getEnabledDigitFields(_ textFieldToDetermine: [DigitBox]) -> [TextField]? {
return textFieldToDetermine.filter { $0.isEnabled }.compactMap { $0.digitField } return textFieldToDetermine.filter { $0.isEnabled }.compactMap { $0.digitField }
} }
@ -352,7 +349,6 @@ import UIKit
// MARK: - TextField Delegate // MARK: - TextField Delegate
extension DigitEntryField { extension DigitEntryField {
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool { @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder() textField.resignFirstResponder()
@ -360,12 +356,7 @@ extension DigitEntryField {
return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true
} }
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { @objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.isBackspace {
selectPreviousDigitField(textField, clear: true)
return true
}
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) { if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
return false return false
@ -400,7 +391,7 @@ extension DigitEntryField {
return false return false
} }
func digitFieldDidDelete(_ textField: UITextField?) { @objc func digitFieldDidDelete(_ textField: UITextField?) {
// Empty cell, go back to previous cell and clear. // Empty cell, go back to previous cell and clear.
selectPreviousDigitField(textField, clear: true) selectPreviousDigitField(textField, clear: true)
@ -454,7 +445,7 @@ extension DigitEntryField {
// MARK: - Molecular // MARK: - Molecular
extension DigitEntryField { extension DigitEntryField {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json else { return } guard let dictionary = json else { return }
@ -473,7 +464,7 @@ extension DigitEntryField {
} }
} }
open override class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { @objc open override class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 115 return 115
} }
} }

View File

@ -49,83 +49,97 @@ import UIKit
weak var delegateObject: MVMCoreUIDelegateObject? weak var delegateObject: MVMCoreUIDelegateObject?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Stored Properties
//-------------------------------------------------- //--------------------------------------------------
public var isValid = false public var isValid: Bool = false
public var fieldKey: String? public var fieldKey: String?
public var errorMessage: String? public var errorMessage: String?
/// Determines whther the feedback label will clear itself after user interaction or display update.
// public var fixedFeedback: Bool = false
private var _isEnabled: Bool = true
private var _showError: Bool = false
private var _isLocked: Bool = false
private var _isSelected: Bool = false
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Property Observers // MARK: - Computed Properties
//-------------------------------------------------- //--------------------------------------------------
/// Toggles error or original UI. /// Toggles enabled (original) or disabled UI.
public var showError = false { public var isEnabled: Bool {
willSet { get { return _isEnabled }
isLocked = false set (enabled) {
isSelected = false
isEnabled = false _isEnabled = enabled
} _isLocked = false
didSet { _isSelected = false
_showError = false
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.entryContainer.showError = self.showError self.entryContainer.isEnabled = enabled
self.feedback = self.showError ? self.errorMessage : nil self.feedbackLabel.textColor = enabled ? .black : .mfSilver()
self.titleLabel.textColor = enabled ? .mfBattleshipGrey() : .mfSilver()
} }
} }
} }
/// Toggles enabled (original) or disabled UI. /// Toggles error or original UI.
public var isEnabled = true { public var showError: Bool {
willSet { get { return _showError }
isLocked = false set (error) {
isSelected = false
showError = false _showError = error
} _isLocked = false
didSet { _isSelected = false
_isEnabled = true
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.isUserInteractionEnabled = self.isEnabled self.entryContainer.showError = error
self.entryContainer.isEnabled = self.isEnabled self.feedback = error ? self.errorMessage : nil
self.feedbackLabel.textColor = self.isEnabled ? .black : .mfSilver()
self.titleLabel.textColor = self.isEnabled ? .mfBattleshipGrey() : .mfSilver()
} }
} }
} }
/// Toggles original or locked UI. /// Toggles original or locked UI.
public var isLocked = false { public var isLocked: Bool {
willSet { get { return _isLocked }
isEnabled = true set (locked) {
isSelected = false
showError = false _isLocked = locked
} _isEnabled = true
didSet { _isSelected = false
_showError = false
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.isUserInteractionEnabled = !self.isLocked self.entryContainer.isLocked = locked
self.entryContainer.isLocked = self.isLocked
} }
} }
} }
/// Toggles selected or original (unselected) UI. /// Toggles selected or original (unselected) UI.
public var isSelected = false { public var isSelected: Bool {
willSet { get { return _isSelected }
isLocked = false set (selected) {
isEnabled = true
showError = false _isSelected = selected
} _isLocked = false
didSet { _isEnabled = true
_showError = false
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.entryContainer.isSelected = self.isSelected self.entryContainer.isSelected = selected
} }
} }
} }
@ -137,9 +151,9 @@ import UIKit
/// Sets the text of titleLabel /// Sets the text of titleLabel
public var title: String? { public var title: String? {
get { return titleLabel.text } get { return titleLabel.text }
set { set (newText) {
titleLabel.text = newValue titleLabel.text = newText
setAccessibilityString(newValue) setAccessibilityString(newText)
} }
} }
@ -152,9 +166,9 @@ import UIKit
/// Sets feedback text in the textField. /// Sets feedback text in the textField.
public var feedback: String? { public var feedback: String? {
get { return feedbackLabel.text } get { return feedbackLabel.text }
set { set (newFeedback) {
feedbackLabel.text = newValue feedbackLabel.text = newFeedback
setAccessibilityString(newValue) setAccessibilityString(newFeedback)
entryContainer.refreshUI() entryContainer.refreshUI()
} }
} }
@ -180,21 +194,21 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
/// This must be overriden by a subclass. /// This must be overriden by a subclass.
public override init(frame: CGRect) { @objc public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
} }
public convenience init() { @objc public convenience init() {
self.init(frame: .zero) self.init(frame: .zero)
} }
public init(title: String) { @objc public init(title: String) {
super.init(frame: .zero) super.init(frame: .zero)
titleLabel.text = title titleLabel.text = title
} }
required public init?(coder: NSCoder) { @objc required public init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
fatalError("EntryField does not support xib.") fatalError("EntryField does not support xib.")
} }
@ -204,7 +218,7 @@ import UIKit
//-------------------------------------------------- //--------------------------------------------------
/// Initial configuration of class and view. /// Initial configuration of class and view.
final public override func setupView() { @objc final public override func setupView() {
guard subviews.isEmpty else { return } guard subviews.isEmpty else { return }
@ -243,7 +257,7 @@ import UIKit
layoutMarginsGuide.bottomAnchor.constraint(equalTo: feedbackLabel.bottomAnchor).isActive = true layoutMarginsGuide.bottomAnchor.constraint(equalTo: feedbackLabel.bottomAnchor).isActive = true
} }
open override func layoutSubviews() { @objc open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
entryContainer.refreshUI() entryContainer.refreshUI()
@ -251,11 +265,11 @@ import UIKit
/// Method to override. /// Method to override.
/// Intended to add the interactive content (i.e. textField) to the entryContainer. /// Intended to add the interactive content (i.e. textField) to the entryContainer.
open func setupFieldContainerContent(_ container: UIView) { @objc open func setupFieldContainerContent(_ container: UIView) {
// To be overridden by subclass. // To be overridden by subclass.
} }
open override func updateView(_ size: CGFloat) { @objc open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
titleLabel.updateView(size) titleLabel.updateView(size)
@ -263,13 +277,18 @@ import UIKit
entryContainer.updateView(size) entryContainer.updateView(size)
} }
open override func reset() { @objc open override func reset() {
super.reset() super.reset()
isEnabled = true
_isLocked = false
_isSelected = false
_showError = false
backgroundColor = .clear backgroundColor = .clear
titleLabel.reset() titleLabel.reset()
feedbackLabel.reset() feedbackLabel.reset()
entryContainer.subviews.forEach { $0.removeFromSuperview() } entryContainer.reset()
titleLabel.textColor = .mfBattleshipGrey() titleLabel.textColor = .mfBattleshipGrey()
} }
@ -277,14 +296,14 @@ import UIKit
// MARK: - Constraint Methods // MARK: - Constraint Methods
//-------------------------------------------------- //--------------------------------------------------
open override func setLeftPinConstant(_ constant: CGFloat) { @objc open override func setLeftPinConstant(_ constant: CGFloat) {
entryContainerLeading?.constant = constant entryContainerLeading?.constant = constant
feedbackLabelLeading?.constant = constant feedbackLabelLeading?.constant = constant
titleLabelLeading?.constant = constant titleLabelLeading?.constant = constant
} }
open override func setRightPinConstant(_ constant: CGFloat) { @objc open override func setRightPinConstant(_ constant: CGFloat) {
entryContainerTrailing?.constant = constant entryContainerTrailing?.constant = constant
feedbackLabelTrailing?.constant = constant feedbackLabelTrailing?.constant = constant
@ -295,7 +314,7 @@ import UIKit
// MARK: - Molecular // MARK: - Molecular
extension EntryField { extension EntryField {
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
self.delegateObject = delegateObject self.delegateObject = delegateObject
@ -303,7 +322,7 @@ extension EntryField {
entryContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData) entryContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
if let titleText = dictionary["title"] as? String { if let titleText = dictionary[KeyTitle] as? String {
title = titleText title = titleText
} }
@ -319,13 +338,17 @@ extension EntryField {
self.isLocked = isLocked self.isLocked = isLocked
} }
if let isSelected = dictionary["isSelected"] as? Bool {
self.isSelected = isSelected
}
// Key used to send text value to server // Key used to send text value to server
if let fieldKey = dictionary[KeyFieldKey] as? String { if let fieldKey = dictionary[KeyFieldKey] as? String {
self.fieldKey = fieldKey self.fieldKey = fieldKey
} }
} }
override open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { @objc override open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 115 return 115
} }
} }
@ -333,15 +356,15 @@ extension EntryField {
// MARK: - Form Validation // MARK: - Form Validation
extension EntryField: FormValidationProtocol { extension EntryField: FormValidationProtocol {
public func isValidField() -> Bool { @objc public func isValidField() -> Bool {
return isValid return isValid
} }
public func formFieldName() -> String? { @objc public func formFieldName() -> String? {
return fieldKey return fieldKey
} }
public func formFieldValue() -> Any? { @objc public func formFieldValue() -> Any? {
return text return text
} }
} }

View File

@ -9,7 +9,7 @@
import UIKit import UIKit
open class ItemDropdownEntryField: DropdownEntryField { open class ItemDropdownEntryField: BaseDropdownEntryField {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -19,59 +19,49 @@ open class ItemDropdownEntryField: DropdownEntryField {
public var componentsCount = 1 public var componentsCount = 1
/// When selecting first responder, allow initial selected value to appear in empty text field. /// When selecting for first responder, allow initial selected value to appear in empty text field.
public var setInitialValueInTextField = true public var setInitialValueInTextField = true
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
private weak var proprietorTextDelegate: UITextFieldDelegate?
/// If you're using a MFViewController, you must set this to it
public override weak var uiTextFieldDelegate: UITextFieldDelegate? {
get { return textField.delegate }
set {
textField.delegate = self
proprietorTextDelegate = newValue
}
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------
public convenience init() { @objc public override init(frame: CGRect) {
self.init(frame: .zero) super.init(frame: frame)
setup() setup()
} }
public convenience init(pickerData: [String]) { @objc public convenience init() {
self.init(frame: .zero)
}
@objc public convenience init(pickerData: [String]) {
self.init(frame: .zero) self.init(frame: .zero)
self.pickerData = pickerData self.pickerData = pickerData
setup()
} }
private func setup() { @objc required public init?(coder: NSCoder) {
fatalError("ItemDropdownEntryField init(coder:) has not been implemented")
pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self)
textField.hideBlinkingCaret = true
uiTextFieldDelegate = self
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) { @objc private func setup() {
pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self)
textField.hideBlinkingCaret = true
uiTextFieldDelegate = self
}
@objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) {
pickerView?.delegate = delegate pickerView?.delegate = delegate
pickerView?.dataSource = delegate pickerView?.dataSource = delegate
} }
private func setInitialValueFromPicker() { @objc private func setInitialValueFromPicker() {
if setInitialValueInTextField, let pickerIndex = pickerView?.selectedRow(inComponent: 0) { if setInitialValueInTextField, let pickerIndex = pickerView?.selectedRow(inComponent: 0) {
text = pickerData[pickerIndex] text = pickerData[pickerIndex]
@ -88,19 +78,19 @@ open class ItemDropdownEntryField: DropdownEntryField {
// MARK:- Base Picker Delegate // MARK:- Base Picker Delegate
extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource { extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
public func numberOfComponents(in pickerView: UIPickerView) -> Int { @objc public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return componentsCount return componentsCount
} }
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { @objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count return pickerData.count
} }
public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { @objc public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row] return pickerData[row]
} }
public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { @objc public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
text = pickerData[row] text = pickerData[row]
} }
} }
@ -108,7 +98,7 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
// MARK: - Molecular // MARK: - Molecular
extension ItemDropdownEntryField { extension ItemDropdownEntryField {
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json, !dictionary.isEmpty else { return } guard let dictionary = json, !dictionary.isEmpty else { return }
@ -119,20 +109,10 @@ extension ItemDropdownEntryField {
} }
} }
// MARK: - UITextField Intercept // MARK: - Accessibility
extension ItemDropdownEntryField { extension ItemDropdownEntryField {
public func textFieldDidBeginEditing(_ textField: UITextField) { @objc open override func setAccessibilityString(_ accessibilityString: String?) {
setInitialValueFromPicker()
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
}
}
// MARK: - Accessibility
extension DropdownEntryField {
open override func setAccessibilityString(_ accessibilityString: String?) {
var accessibilityString = accessibilityString ?? "" var accessibilityString = accessibilityString ?? ""

View File

@ -16,7 +16,7 @@ import MVMCore
*/ */
@objcMembers open class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate { @objcMembers open class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Stored Properties
//-------------------------------------------------- //--------------------------------------------------
public var isNationalMDN = true public var isNationalMDN = true
@ -30,7 +30,7 @@ import MVMCore
private weak var proprietorTextDelegate: UITextFieldDelegate? private weak var proprietorTextDelegate: UITextFieldDelegate?
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Property Observers // MARK: - Computed Properties
//-------------------------------------------------- //--------------------------------------------------
/// Formats the MDN when setting and removes format of MDN when reading. /// Formats the MDN when setting and removes format of MDN when reading.
@ -52,21 +52,15 @@ import MVMCore
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public override init(frame: CGRect) { @objc public override init(frame: CGRect) {
super.init(frame: .zero) super.init(frame: .zero)
} }
public convenience init() { @objc public convenience init() {
self.init(frame: .zero) self.init(frame: .zero)
} }
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates. @objc required public init?(coder: NSCoder) {
public override init(bothDelegates: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
super.init(frame: .zero)
setBothTextDelegates(to: bothDelegates)
}
required public init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
fatalError("MdnEntryField xib not supported.") fatalError("MdnEntryField xib not supported.")
} }
@ -75,7 +69,7 @@ import MVMCore
// MARK: - Setup // MARK: - Setup
//-------------------------------------------------- //--------------------------------------------------
public override func setupFieldContainerContent(_ container: UIView) { @objc public override func setupFieldContainerContent(_ container: UIView) {
super.setupFieldContainerContent(container) super.setupFieldContainerContent(container)
textField.keyboardType = .numberPad textField.keyboardType = .numberPad
@ -92,7 +86,7 @@ import MVMCore
// MARK: - Methods // MARK: - Methods
//-------------------------------------------------- //--------------------------------------------------
public func hasValidMDN() -> Bool { @objc public func hasValidMDN() -> Bool {
guard let MDN = mdn, !MDN.isEmpty else { return true } guard let MDN = mdn, !MDN.isEmpty else { return true }
@ -103,13 +97,13 @@ import MVMCore
return MVMCoreUIUtility.validateInternationalMDNString(MDN) return MVMCoreUIUtility.validateInternationalMDNString(MDN)
} }
public func validateAndColor() -> Bool { @objc public func validateAndColor() -> Bool {
if !shouldValidateMDN { if !shouldValidateMDN {
let isValid = hasValidMDN() let isValid = hasValidMDN()
if isValid { if isValid {
clearErrorState() showError = false
} else { } else {
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
showError = true showError = true
@ -136,7 +130,7 @@ import MVMCore
// MARK: - Contact Picker Delegate // MARK: - Contact Picker Delegate
//-------------------------------------------------- //--------------------------------------------------
public func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) { @objc public func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
if let phoneNumber = contactProperty.value as? CNPhoneNumber { if let phoneNumber = contactProperty.value as? CNPhoneNumber {
@ -163,14 +157,14 @@ import MVMCore
// MARK: - Implemented TextField Delegate // MARK: - Implemented TextField Delegate
//-------------------------------------------------- //--------------------------------------------------
public func textFieldShouldReturn(_ textField: UITextField) -> Bool { @objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder() textField.resignFirstResponder()
return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true
} }
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { @objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) { if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
return false return false
@ -179,13 +173,13 @@ import MVMCore
return proprietorTextDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true return proprietorTextDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
} }
public func textFieldDidBeginEditing(_ textField: UITextField) { @objc public func textFieldDidBeginEditing(_ textField: UITextField) {
textField.text = MVMCoreUIUtility.removeMdnFormat(textField.text) textField.text = MVMCoreUIUtility.removeMdnFormat(textField.text)
proprietorTextDelegate?.textFieldDidBeginEditing?(textField) proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
} }
public func textFieldDidEndEditing(_ textField: UITextField) { @objc public func textFieldDidEndEditing(_ textField: UITextField) {
proprietorTextDelegate?.textFieldDidEndEditing?(textField) proprietorTextDelegate?.textFieldDidEndEditing?(textField)
@ -194,21 +188,17 @@ import MVMCore
} }
} }
//-------------------------------------------------- @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
// MARK: - Passed Along TextField delegate
//--------------------------------------------------
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
} }
public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { @objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
} }
public func textFieldShouldClear(_ textField: UITextField) -> Bool { @objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
return proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true return proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
} }

View File

@ -36,30 +36,41 @@ import UIKit
}() }()
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Stored Properties
//-------------------------------------------------- //--------------------------------------------------
/// Set enabled and disabled colors to be utilized when setting this texfield's isEnabled property. /// Set enabled and disabled colors to be utilized when setting this texfield's isEnabled property.
public var textColor: (enabled: UIColor?, disabled: UIColor?) = (.black, .mfSilver()) public var textColor: (enabled: UIColor?, disabled: UIColor?) = (.black, .mfSilver())
public var observingForChange = false public var observingForChange: Bool = false
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Property Observers // MARK: - Computed Properties
//-------------------------------------------------- //--------------------------------------------------
public override var isEnabled: Bool { public override var isEnabled: Bool {
didSet { get { return super.isEnabled }
set (enabled) {
super.isEnabled = enabled
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.textField.isEnabled = self.isEnabled self.textField.isEnabled = enabled
self.textField.textColor = self.isEnabled ? self.textColor.enabled : self.textColor.disabled self.textField.textColor = enabled ? self.textColor.enabled : self.textColor.disabled
} }
} }
} }
/// The text of this textField. public override var showError: Bool {
get { return super.showError }
set (error) {
textField.accessibilityValue = nil
super.showError = error
}
}
/// The text of this TextField.
public override var text: String? { public override var text: String? {
get { return textField.text } get { return textField.text }
set { set {
@ -74,6 +85,10 @@ import UIKit
set { textField.placeholder = newValue } set { textField.placeholder = newValue }
} }
//--------------------------------------------------
// MARK: - Property Observers
//--------------------------------------------------
public var validationBlock: ((_ value: String?) -> Bool)? { public var validationBlock: ((_ value: String?) -> Bool)? {
didSet { valueChanged() } didSet { valueChanged() }
} }
@ -122,21 +137,15 @@ import UIKit
// MARK: - Initializers // MARK: - Initializers
//-------------------------------------------------- //--------------------------------------------------
public override init(frame: CGRect) { @objc public override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
} }
public convenience init() { @objc public convenience init() {
self.init(frame: .zero) self.init(frame: .zero)
} }
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates. @objc required public init?(coder: NSCoder) {
public init(bothDelegates: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
super.init(frame: .zero)
setBothTextDelegates(to: bothDelegates)
}
required public init?(coder: NSCoder) {
super.init(coder: coder) super.init(coder: coder)
fatalError("TextEntryField does not support xib.") fatalError("TextEntryField does not support xib.")
} }
@ -145,7 +154,7 @@ import UIKit
// MARK: - Lifecycle // MARK: - Lifecycle
//-------------------------------------------------- //--------------------------------------------------
open override func setupFieldContainerContent(_ container: UIView) { @objc open override func setupFieldContainerContent(_ container: UIView) {
MFStyler.styleTextField(textField) MFStyler.styleTextField(textField)
container.addSubview(textField) container.addSubview(textField)
@ -162,42 +171,28 @@ import UIKit
accessibilityElements = [titleLabel, textField, feedbackLabel] accessibilityElements = [titleLabel, textField, feedbackLabel]
} }
open override func updateView(_ size: CGFloat) { @objc open override func updateView(_ size: CGFloat) {
super.updateView(size) super.updateView(size)
MFStyler.styleTextField(textField) MFStyler.styleTextField(textField)
layoutIfNeeded() layoutIfNeeded()
} }
deinit { @objc deinit {
setBothTextDelegates(to: nil) setBothTextDelegates(to: nil)
} }
//-------------------------------------------------- @objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
// MARK: - Methods
//--------------------------------------------------
open func clearErrorState() {
textField.accessibilityValue = nil
feedback = nil
showError = false
}
public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
observingTextFieldDelegate = delegate observingTextFieldDelegate = delegate
uiTextFieldDelegate = delegate uiTextFieldDelegate = delegate
} }
public func defaultValidationBlock() { //--------------------------------------------------
// MARK: - Observing for Change (TextFieldDelegate)
validationBlock = { enteredValue in //--------------------------------------------------
return (enteredValue?.count ?? 0) > 0
}
}
override open func resignFirstResponder() -> Bool { @objc override open func resignFirstResponder() -> Bool {
textField.resignFirstResponder() textField.resignFirstResponder()
isSelected = false isSelected = false
@ -209,10 +204,14 @@ import UIKit
_ = self.resignFirstResponder() _ = self.resignFirstResponder()
} }
//-------------------------------------------------- public func defaultValidationBlock() {
// MARK: - Observing for Change (TextFieldDelegate)
//-------------------------------------------------- validationBlock = { enteredValue in
return (enteredValue?.count ?? 0) > 0
}
}
/// Executes on UITextField.textDidChangeNotification
@objc func valueChanged() { @objc func valueChanged() {
if !showError { if !showError {
@ -225,19 +224,20 @@ import UIKit
isValid = validationBlock?(text) ?? true isValid = validationBlock?(text) ?? true
if previousValidity && !isValid { if previousValidity && !isValid {
feedback = errorMessage showError = true
observingTextFieldDelegate?.isInvalid?(textfield: self) observingTextFieldDelegate?.isInvalid?(textfield: self)
} else if !previousValidity && isValid { } else if !previousValidity && isValid {
clearErrorState() showError = false
observingTextFieldDelegate?.isValid?(textfield: self) observingTextFieldDelegate?.isValid?(textfield: self)
} }
} }
/// Executes on UITextField.textDidEndEditingNotification
@objc func endInputing() { @objc func endInputing() {
if isValid { if isValid {
clearErrorState() showError = false
entryContainer.bottomBar?.backgroundColor = UIColor.black.cgColor entryContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
} else if let errMessage = errorMessage { } else if let errMessage = errorMessage {
@ -245,6 +245,7 @@ import UIKit
} }
} }
/// Executes on UITextField.textDidBeginEditingNotification
@objc func startEditing() { @objc func startEditing() {
isSelected = true isSelected = true
@ -255,7 +256,7 @@ import UIKit
// MARK: - Molecular // MARK: - Molecular
extension TextEntryField { extension TextEntryField {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { @objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let delegateObject = delegateObject, guard let delegateObject = delegateObject,
@ -306,7 +307,7 @@ extension TextEntryField {
} }
if let formValidationProtocol = delegateObject.formValidationProtocol { if let formValidationProtocol = delegateObject.formValidationProtocol {
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol) as? ObservingTextFieldDelegate observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
} }
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
@ -317,7 +318,7 @@ extension TextEntryField {
// MARK: - Accessibility // MARK: - Accessibility
extension TextEntryField { extension TextEntryField {
open override func pushAccessibilityNotification() { @objc open override func pushAccessibilityNotification() {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
@ -326,7 +327,7 @@ extension TextEntryField {
} }
} }
open override func setAccessibilityString(_ accessibilityString: String?) { @objc open override func setAccessibilityString(_ accessibilityString: String?) {
var accessibilityString = accessibilityString ?? "" var accessibilityString = accessibilityString ?? ""

View File

@ -18,7 +18,7 @@
public var direction: Direction = .right public var direction: Direction = .right
public var size: CaretSize? public var size: CaretSize?
public var enabledColor: UIColor = .black public var enabledColor: UIColor = .black
public var disabledColor: UIColor = .mfSilver() public var disabledColor: UIColor = .mfSilver()
@ -48,17 +48,17 @@
case vertical case vertical
case horizontal case horizontal
} }
// Dimensions of container; provided by InVision. // Dimensions of container; provided by InVision design.
func dimensions() -> CGSize { func dimensions() -> CGSize {
switch self { switch self {
case .small(let o): case .small(let o):
return o == .vertical ? CGSize(width: 6, height: 10) : CGSize(width: 10, height: 6) return o == .vertical ? CGSize(width: 6, height: 10) : CGSize(width: 10, height: 6)
case .medium(let o): case .medium(let o):
return o == .vertical ? CGSize(width: 9, height: 16) : CGSize(width: 16, height: 9) return o == .vertical ? CGSize(width: 9, height: 16) : CGSize(width: 16, height: 9)
case .large(let o): case .large(let o):
return o == .vertical ? CGSize(width: 14, height: 24) : CGSize(width: 24, height: 14) return o == .vertical ? CGSize(width: 14, height: 24) : CGSize(width: 24, height: 14)
} }
@ -114,7 +114,7 @@
caretPath.removeAllPoints() caretPath.removeAllPoints()
caretPath.lineJoinStyle = .miter caretPath.lineJoinStyle = .miter
caretPath.lineWidth = lineWidth caretPath.lineWidth = lineWidth
let inset = lineWidth / 2 let inset = lineWidth / 2
let halfWidth = frame.size.width / 2 let halfWidth = frame.size.width / 2
let halfHeight = frame.size.height / 2 let halfHeight = frame.size.height / 2
@ -168,7 +168,7 @@
@objc public func setConstraints() { @objc public func setConstraints() {
guard let dimensions = size?.dimensions() else { return } guard let dimensions = size?.dimensions() else { return }
heightAnchor.constraint(equalToConstant: dimensions.height).isActive = true heightAnchor.constraint(equalToConstant: dimensions.height).isActive = true
widthAnchor.constraint(equalToConstant: dimensions.width).isActive = true widthAnchor.constraint(equalToConstant: dimensions.width).isActive = true
} }
@ -191,16 +191,16 @@
strokeColor = UIColor.mfGet(forHex: strokeColorHex) strokeColor = UIColor.mfGet(forHex: strokeColorHex)
} }
if let isHiddenValue = dictionary[KeyIsHidden] as? Bool { if let isHidden = dictionary[KeyIsHidden] as? Bool {
isHidden = isHiddenValue self.isHidden = isHidden
} }
if let isOpaqueValue = dictionary[KeyIsOpaque] as? Bool { if let isOpaque = dictionary[KeyIsOpaque] as? Bool {
isOpaque = isOpaqueValue self.isOpaque = isOpaque
} }
if let lineWidthValue = dictionary["lineWidth"] as? CGFloat { if let lineWidth = dictionary["lineWidth"] as? CGFloat {
lineWidth = lineWidthValue self.lineWidth = lineWidth
} }
} }

View File

@ -29,7 +29,6 @@ open class TextField: UITextField {
// MARK: - Delegate // MARK: - Delegate
//-------------------------------------------------- //--------------------------------------------------
/// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well.
private weak var proprietorTextDelegate: UITextFieldDelegate? private weak var proprietorTextDelegate: UITextFieldDelegate?

View File

@ -23,14 +23,23 @@ import UIKit
return layer return layer
}() }()
/// Total control over bottom bar and the drawn borders. /// Total control overthe drawn top,bottom, left and right borders.
public var disableBorders = false { public var disableAllBorders = false {
didSet { didSet {
bottomBar?.isHidden = disableBorders bottomBar?.isHidden = disableAllBorders
} }
} }
/// Determines if a border should be drawn. private(set) var fieldState: FieldState = .original {
didSet (oldState) {
// Will not update if new state is the same as old.
if fieldState != oldState {
fieldState.setStateUI(for: self)
}
}
}
/// Determines if the top, left, and right borders should be drawn.
private var hideBorders = false private var hideBorders = false
public var borderStrokeColor: UIColor = .mfSilver() public var borderStrokeColor: UIColor = .mfSilver()
@ -40,27 +49,60 @@ import UIKit
// MARK: - Property Observers // MARK: - Property Observers
//-------------------------------------------------- //--------------------------------------------------
public var showError = false { private var _isEnabled: Bool = true
didSet { private var _showError: Bool = false
showError ? errorUI() : originalUI() private var _isLocked: Bool = false
private var _isSelected: Bool = false
public var isEnabled: Bool {
get { return _isEnabled }
set (enabled) {
_isEnabled = enabled
_isLocked = false
_isSelected = false
_showError = false
fieldState = enabled ? .original : .disabled
} }
} }
public var isEnabled = true { public var showError: Bool {
didSet { get { return _showError }
isEnabled ? originalUI() : disabledUI() set (error) {
_showError = error
_isEnabled = true
_isLocked = false
_isSelected = false
fieldState = error ? .error : .original
} }
} }
public var isLocked = false { public var isLocked: Bool {
didSet { get { return _isLocked }
isLocked ? lockedUI() : originalUI() set (locked) {
_isLocked = locked
_isEnabled = true
_isSelected = false
_showError = false
fieldState = locked ? .locked : .original
} }
} }
public var isSelected = false { public var isSelected: Bool {
didSet { get { return _isSelected }
isSelected ? selectedUI() : originalUI() set (selected) {
_isSelected = selected
_isLocked = false
_isEnabled = true
_showError = false
fieldState = selected ? .selected : .original
} }
} }
@ -93,7 +135,7 @@ import UIKit
borderPath.removeAllPoints() borderPath.removeAllPoints()
if !disableBorders && !hideBorders { if !disableAllBorders && !hideBorders {
// Brings the other half of the line inside the view to prevent cropping. // Brings the other half of the line inside the view to prevent cropping.
let origin = bounds.origin let origin = bounds.origin
let size = frame.size let size = frame.size
@ -119,11 +161,22 @@ import UIKit
} }
} }
open override func reset() {
super.reset()
isEnabled = true
_isLocked = false
_isSelected = false
_showError = false
subviews.forEach { $0.removeFromSuperview() }
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Draw States // MARK: - Draw States
//-------------------------------------------------- //--------------------------------------------------
public enum State { public enum FieldState {
case original case original
case error case error
case selected case selected
@ -162,8 +215,8 @@ import UIKit
open func errorUI() { open func errorUI() {
isUserInteractionEnabled = true isUserInteractionEnabled = true
borderStrokeColor = .mfPumpkin()
hideBorders = false hideBorders = false
borderStrokeColor = .mfPumpkin()
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
refreshUI(bottomBarSize: 4) refreshUI(bottomBarSize: 4)
} }
@ -171,8 +224,8 @@ import UIKit
open func selectedUI() { open func selectedUI() {
isUserInteractionEnabled = true isUserInteractionEnabled = true
borderStrokeColor = .black
hideBorders = false hideBorders = false
borderStrokeColor = .black
bottomBar?.backgroundColor = UIColor.black.cgColor bottomBar?.backgroundColor = UIColor.black.cgColor
refreshUI(bottomBarSize: 1) refreshUI(bottomBarSize: 1)
} }
@ -180,8 +233,8 @@ import UIKit
open func lockedUI() { open func lockedUI() {
isUserInteractionEnabled = false isUserInteractionEnabled = false
borderStrokeColor = .clear
hideBorders = true hideBorders = true
borderStrokeColor = .clear
bottomBar?.backgroundColor = UIColor.clear.cgColor bottomBar?.backgroundColor = UIColor.clear.cgColor
refreshUI(bottomBarSize: 1) refreshUI(bottomBarSize: 1)
} }
@ -189,15 +242,15 @@ import UIKit
open func disabledUI() { open func disabledUI() {
isUserInteractionEnabled = false isUserInteractionEnabled = false
borderStrokeColor = .mfSilver()
hideBorders = false hideBorders = false
borderStrokeColor = .mfSilver()
bottomBar?.backgroundColor = UIColor.mfSilver().cgColor bottomBar?.backgroundColor = UIColor.mfSilver().cgColor
refreshUI(bottomBarSize: 1) refreshUI(bottomBarSize: 1)
} }
open func refreshUI(bottomBarSize: CGFloat? = nil) { open func refreshUI(bottomBarSize: CGFloat? = nil) {
if !disableBorders { if !disableAllBorders {
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1) let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size) bottomBar?.frame = CGRect(x: 0, y: bounds.height - size, width: bounds.width, height: size)
@ -217,8 +270,8 @@ import UIKit
guard let dictionary = json, !dictionary.isEmpty else { return } guard let dictionary = json, !dictionary.isEmpty else { return }
if let disableBorders = dictionary["disableBorders"] as? Bool { if let disableAllBorders = dictionary["disableAllBorders"] as? Bool {
self.disableBorders = disableBorders self.disableAllBorders = disableAllBorders
} }
} }
} }

View File

@ -38,8 +38,9 @@
@"caretButton": CaretButton.class, @"caretButton": CaretButton.class,
@"textField": TextEntryField.class, @"textField": TextEntryField.class,
@"digitEntryField": DigitEntryField.class, @"digitEntryField": DigitEntryField.class,
@"itemDropdownEntryField": ItemDropdownEntryField.class,
@"dateDropdownEntryField": DateDropdownEntryField.class,
@"mdnEntryField" : MdnEntryField.class, @"mdnEntryField" : MdnEntryField.class,
@"dropdownEntryField" : DropdownEntryField.class,
@"checkbox" : Checkbox.class, @"checkbox" : Checkbox.class,
@"checkboxWithLabel" : CheckboxWithLabelView.class, @"checkboxWithLabel" : CheckboxWithLabelView.class,
@"cornerLabels" : CornerLabels.class, @"cornerLabels" : CornerLabels.class,