latest.
This commit is contained in:
parent
26c73070d9
commit
88442fe59c
@ -42,10 +42,10 @@
|
||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.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 */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -452,7 +452,7 @@
|
||||
0ABD1369237B18EE0081388D /* views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0ABD136A237B193A0081388D /* FormView.swift */,
|
||||
0ABD136A237B193A0081388D /* FormFieldContainer.swift */,
|
||||
);
|
||||
path = views;
|
||||
sourceTree = "<group>";
|
||||
@ -809,7 +809,7 @@
|
||||
0A21DB7E235DECC500C160A2 /* EntryField.swift */,
|
||||
0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */,
|
||||
0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */,
|
||||
0A6BF4712360C56C0028F841 /* DropdownEntryField.swift */,
|
||||
0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */,
|
||||
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */,
|
||||
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */,
|
||||
);
|
||||
@ -1187,14 +1187,14 @@
|
||||
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
|
||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
|
||||
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
|
||||
0A6BF4722360C56C0028F841 /* DropdownEntryField.swift in Sources */,
|
||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */,
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */,
|
||||
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
|
||||
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
|
||||
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */,
|
||||
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */,
|
||||
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
|
||||
0ABD136B237B193A0081388D /* FormView.swift in Sources */,
|
||||
0ABD136B237B193A0081388D /* FormFieldContainer.swift in Sources */,
|
||||
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */,
|
||||
D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */,
|
||||
D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// DropdownEntryField.swift
|
||||
// BaseDropdownEntryField.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 10/23/19.
|
||||
@ -9,10 +9,10 @@
|
||||
import UIKit
|
||||
|
||||
/**
|
||||
This class is intended to be subclassed.
|
||||
See ItemDropdownEntryField and DateDropdownEntryField.
|
||||
This class is intended to be subclassed.
|
||||
See ItemDropdownEntryField and DateDropdownEntryField.
|
||||
*/
|
||||
@objcMembers open class DropdownEntryField: TextEntryField {
|
||||
@objcMembers open class BaseDropdownEntryField: TextEntryField {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -31,9 +31,11 @@ import UIKit
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
dropDownCaretView.isEnabled = isEnabled
|
||||
@objc public override var isEnabled: Bool {
|
||||
get { super.isEnabled }
|
||||
set (enabled) {
|
||||
dropDownCaretView.isEnabled = enabled
|
||||
super.isEnabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,11 +43,11 @@ import UIKit
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("DropdownEntryField does not support xib.")
|
||||
}
|
||||
@ -54,7 +56,7 @@ import UIKit
|
||||
// MARK: - Setup
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setupFieldContainerContent(_ container: UIView) {
|
||||
@objc public override func setupFieldContainerContent(_ container: UIView) {
|
||||
super.setupFieldContainerContent(container)
|
||||
|
||||
container.addSubview(dropDownCaretView)
|
||||
@ -66,7 +68,6 @@ import UIKit
|
||||
|
||||
container.trailingAnchor.constraint(equalTo: dropDownCaretView.trailingAnchor, constant: 16).isActive = true
|
||||
container.bottomAnchor.constraint(greaterThanOrEqualTo: dropDownCaretView.bottomAnchor, constant: 13).isActive = true
|
||||
|
||||
dropDownCaretView.centerYAnchor.constraint(equalTo: container.centerYAnchor).isActive = true
|
||||
|
||||
let caretTap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||
@ -75,15 +76,13 @@ import UIKit
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
||||
|
||||
if let _ = dictionary[KeyType] as? String {
|
||||
dropDownCaretView.isHidden = false
|
||||
}
|
||||
dropDownCaretView.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
open class DateDropdownEntryField: DropdownEntryField {
|
||||
@objcMembers open class DateDropdownEntryField: BaseDropdownEntryField {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -32,44 +32,41 @@ open class DateDropdownEntryField: DropdownEntryField {
|
||||
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
|
||||
//--------------------------------------------------
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
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)
|
||||
|
||||
setup()
|
||||
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?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
|
||||
datePicker?.timeZone = NSTimeZone.system
|
||||
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?.maximumDate = endDate
|
||||
@ -79,7 +76,7 @@ open class DateDropdownEntryField: DropdownEntryField {
|
||||
}
|
||||
}
|
||||
|
||||
public func dismissDatePicker() -> Date? {
|
||||
@objc public func dismissDatePicker() -> Date? {
|
||||
|
||||
let pickedDate = datePicker?.date
|
||||
setTextWith(date: pickedDate)
|
||||
@ -88,8 +85,8 @@ open class DateDropdownEntryField: DropdownEntryField {
|
||||
return pickedDate
|
||||
}
|
||||
|
||||
private func setTextWith(date: Date?) {
|
||||
|
||||
@objc private func setTextWith(date: Date?) {
|
||||
|
||||
guard let date = date else { return }
|
||||
|
||||
if calendar.isDate(date, inSameDayAs: Date()) {
|
||||
@ -104,26 +101,16 @@ open class DateDropdownEntryField: DropdownEntryField {
|
||||
super.dismissFieldInput(sender)
|
||||
}
|
||||
|
||||
@objc func pickerValueChanged(_ sender: UIDatePicker){
|
||||
|
||||
setTextWith(date: datePicker?.date)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITextField Intercept
|
||||
extension DateDropdownEntryField {
|
||||
|
||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
@objc func pickerValueChanged(_ sender: UIDatePicker) {
|
||||
|
||||
isSelected = true
|
||||
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
|
||||
setTextWith(date: datePicker?.date)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Molecular
|
||||
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)
|
||||
|
||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
||||
|
||||
@ -8,9 +8,8 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
@objc protocol DigitBoxDelegate: NSObjectProtocol {
|
||||
@objc protocol DigitBoxDelegate {
|
||||
@objc optional func digitFieldDidDelete(_ textField: UITextField?)
|
||||
@objc optional func textFieldDidChange(_ textField: UITextField)
|
||||
}
|
||||
|
||||
|
||||
@ -40,11 +39,12 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public override var showError: Bool {
|
||||
didSet {
|
||||
get { return super.showError }
|
||||
set (error) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.borderStrokeColor = self.showError ? .mfPumpkin() : .mfSilver()
|
||||
self.borderStrokeColor = error ? .mfPumpkin() : .mfSilver()
|
||||
|
||||
let barHeight: CGFloat = self.showError ? 4 : 1
|
||||
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.layoutIfNeeded()
|
||||
}
|
||||
super.showError = error
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,16 +143,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
// 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) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,14 +27,15 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
titleLabel.textColor = self.isEnabled ? .mfBattleshipGrey() : .mfSilver()
|
||||
get { return super.isEnabled }
|
||||
set (enabled) {
|
||||
titleLabel.textColor = enabled ? .mfBattleshipGrey() : .mfSilver()
|
||||
|
||||
digitBoxes.forEach {
|
||||
$0.isEnabled = self.isEnabled
|
||||
$0.isUserInteractionEnabled = isEnabled
|
||||
$0.digitField.isEnabled = isEnabled
|
||||
$0.digitField.textColor = isEnabled ? .black : .mfBattleshipGrey()
|
||||
$0.isEnabled = enabled
|
||||
$0.isUserInteractionEnabled = enabled
|
||||
$0.digitField.isEnabled = enabled
|
||||
$0.digitField.textColor = enabled ? .black : .mfBattleshipGrey()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,8 +47,9 @@ import UIKit
|
||||
}
|
||||
|
||||
public override var isLocked: Bool {
|
||||
didSet {
|
||||
digitBoxes.forEach { $0.isLocked = self.isLocked }
|
||||
get { return super.isLocked }
|
||||
set (locked) {
|
||||
digitBoxes.forEach { $0.isLocked = locked }
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,25 +129,20 @@ import UIKit
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
@objc public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init(numberOfDigits: Int) {
|
||||
@objc public convenience init(numberOfDigits: Int) {
|
||||
self.init(frame: .zero)
|
||||
self.numberOfDigits = numberOfDigits
|
||||
}
|
||||
|
||||
public init(numberOfDigits: Int, bothDelegates delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?, size: CGFloat? = nil) {
|
||||
self.numberOfDigits = numberOfDigits
|
||||
super.init(bothDelegates: delegate)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("DigitEntryField xib has not been implemented")
|
||||
}
|
||||
@ -154,15 +151,15 @@ import UIKit
|
||||
// MARK: - Setup
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setupFieldContainerContent(_ container: UIView) {
|
||||
@objc public override func setupFieldContainerContent(_ container: UIView) {
|
||||
|
||||
alignCenterHorizontal()
|
||||
isAccessibilityElement = false
|
||||
entryContainer.disableBorders = true
|
||||
entryContainer.disableAllBorders = true
|
||||
assembleDigitFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
}
|
||||
|
||||
private func createDigitField() -> DigitBox {
|
||||
@objc private func createDigitField() -> DigitBox {
|
||||
|
||||
let digitBox = DigitBox()
|
||||
digitBox.isAccessibilityElement = true
|
||||
@ -172,7 +169,7 @@ import UIKit
|
||||
return digitBox
|
||||
}
|
||||
|
||||
func assembleDigitFieldsView(size: CGFloat) {
|
||||
@objc func assembleDigitFieldsView(size: CGFloat) {
|
||||
|
||||
var accessibleElements: [Any] = [titleLabel]
|
||||
|
||||
@ -218,10 +215,10 @@ import UIKit
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
@objc open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
entryContainer.disableBorders = true
|
||||
entryContainer.disableAllBorders = true
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@ -234,10 +231,10 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
@objc open override func reset() {
|
||||
super.reset()
|
||||
|
||||
entryContainer.disableBorders = false
|
||||
entryContainer.disableAllBorders = false
|
||||
digitBoxes.forEach { $0.reset() }
|
||||
}
|
||||
|
||||
@ -245,7 +242,7 @@ import UIKit
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func setAsSecureTextEntry(_ secureEntry: Bool) {
|
||||
@objc public func setAsSecureTextEntry(_ secureEntry: Bool) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
@ -259,7 +256,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public override func defaultValidationBlock() {
|
||||
@objc public override func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
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
|
||||
|
||||
@ -292,7 +289,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public func selectNextDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
@objc public func selectNextDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectNextField = false
|
||||
|
||||
@ -326,7 +323,7 @@ import UIKit
|
||||
selectedDigitField?.digitField.becomeFirstResponder()
|
||||
}
|
||||
|
||||
override open func resignFirstResponder() -> Bool {
|
||||
@objc override open func resignFirstResponder() -> Bool {
|
||||
|
||||
selectedDigitField?.digitField.resignFirstResponder()
|
||||
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 }
|
||||
}
|
||||
@ -352,7 +349,6 @@ import UIKit
|
||||
// MARK: - TextField Delegate
|
||||
extension DigitEntryField {
|
||||
|
||||
|
||||
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
|
||||
textField.resignFirstResponder()
|
||||
@ -360,12 +356,7 @@ extension DigitEntryField {
|
||||
return proprietorTextDelegate?.textFieldShouldReturn?(textField) ?? true
|
||||
}
|
||||
|
||||
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
|
||||
if string.isBackspace {
|
||||
selectPreviousDigitField(textField, clear: true)
|
||||
return true
|
||||
}
|
||||
@objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
|
||||
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
|
||||
return false
|
||||
@ -400,7 +391,7 @@ extension DigitEntryField {
|
||||
return false
|
||||
}
|
||||
|
||||
func digitFieldDidDelete(_ textField: UITextField?) {
|
||||
@objc func digitFieldDidDelete(_ textField: UITextField?) {
|
||||
|
||||
// Empty cell, go back to previous cell and clear.
|
||||
selectPreviousDigitField(textField, clear: true)
|
||||
@ -454,7 +445,7 @@ extension DigitEntryField {
|
||||
// MARK: - Molecular
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,83 +49,97 @@ import UIKit
|
||||
weak var delegateObject: MVMCoreUIDelegateObject?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
// MARK: - Stored Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var isValid = false
|
||||
public var isValid: Bool = false
|
||||
public var fieldKey: 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.
|
||||
public var showError = false {
|
||||
willSet {
|
||||
isLocked = false
|
||||
isSelected = false
|
||||
isEnabled = false
|
||||
}
|
||||
didSet {
|
||||
/// Toggles enabled (original) or disabled UI.
|
||||
public var isEnabled: Bool {
|
||||
get { return _isEnabled }
|
||||
set (enabled) {
|
||||
|
||||
_isEnabled = enabled
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryContainer.showError = self.showError
|
||||
self.feedback = self.showError ? self.errorMessage : nil
|
||||
self.entryContainer.isEnabled = enabled
|
||||
self.feedbackLabel.textColor = enabled ? .black : .mfSilver()
|
||||
self.titleLabel.textColor = enabled ? .mfBattleshipGrey() : .mfSilver()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggles enabled (original) or disabled UI.
|
||||
public var isEnabled = true {
|
||||
willSet {
|
||||
isLocked = false
|
||||
isSelected = false
|
||||
showError = false
|
||||
}
|
||||
didSet {
|
||||
/// Toggles error or original UI.
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_isEnabled = true
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.isUserInteractionEnabled = self.isEnabled
|
||||
self.entryContainer.isEnabled = self.isEnabled
|
||||
self.feedbackLabel.textColor = self.isEnabled ? .black : .mfSilver()
|
||||
self.titleLabel.textColor = self.isEnabled ? .mfBattleshipGrey() : .mfSilver()
|
||||
self.entryContainer.showError = error
|
||||
self.feedback = error ? self.errorMessage : nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggles original or locked UI.
|
||||
public var isLocked = false {
|
||||
willSet {
|
||||
isEnabled = true
|
||||
isSelected = false
|
||||
showError = false
|
||||
}
|
||||
didSet {
|
||||
public var isLocked: Bool {
|
||||
get { return _isLocked }
|
||||
set (locked) {
|
||||
|
||||
_isLocked = locked
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.isUserInteractionEnabled = !self.isLocked
|
||||
self.entryContainer.isLocked = self.isLocked
|
||||
self.entryContainer.isLocked = locked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggles selected or original (unselected) UI.
|
||||
public var isSelected = false {
|
||||
willSet {
|
||||
isLocked = false
|
||||
isEnabled = true
|
||||
showError = false
|
||||
}
|
||||
didSet {
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isLocked = false
|
||||
_isEnabled = true
|
||||
_showError = false
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
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
|
||||
public var title: String? {
|
||||
get { return titleLabel.text }
|
||||
set {
|
||||
titleLabel.text = newValue
|
||||
setAccessibilityString(newValue)
|
||||
set (newText) {
|
||||
titleLabel.text = newText
|
||||
setAccessibilityString(newText)
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,9 +166,9 @@ import UIKit
|
||||
/// Sets feedback text in the textField.
|
||||
public var feedback: String? {
|
||||
get { return feedbackLabel.text }
|
||||
set {
|
||||
feedbackLabel.text = newValue
|
||||
setAccessibilityString(newValue)
|
||||
set (newFeedback) {
|
||||
feedbackLabel.text = newFeedback
|
||||
setAccessibilityString(newFeedback)
|
||||
entryContainer.refreshUI()
|
||||
}
|
||||
}
|
||||
@ -180,21 +194,21 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
/// This must be overriden by a subclass.
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
@objc public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
public init(title: String) {
|
||||
@objc public init(title: String) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
titleLabel.text = title
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("EntryField does not support xib.")
|
||||
}
|
||||
@ -204,7 +218,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Initial configuration of class and view.
|
||||
final public override func setupView() {
|
||||
@objc final public override func setupView() {
|
||||
|
||||
guard subviews.isEmpty else { return }
|
||||
|
||||
@ -243,7 +257,7 @@ import UIKit
|
||||
layoutMarginsGuide.bottomAnchor.constraint(equalTo: feedbackLabel.bottomAnchor).isActive = true
|
||||
}
|
||||
|
||||
open override func layoutSubviews() {
|
||||
@objc open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
entryContainer.refreshUI()
|
||||
@ -251,11 +265,11 @@ import UIKit
|
||||
|
||||
/// Method to override.
|
||||
/// 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.
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
@objc open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
titleLabel.updateView(size)
|
||||
@ -263,13 +277,18 @@ import UIKit
|
||||
entryContainer.updateView(size)
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
@objc open override func reset() {
|
||||
super.reset()
|
||||
|
||||
isEnabled = true
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
backgroundColor = .clear
|
||||
titleLabel.reset()
|
||||
feedbackLabel.reset()
|
||||
entryContainer.subviews.forEach { $0.removeFromSuperview() }
|
||||
entryContainer.reset()
|
||||
titleLabel.textColor = .mfBattleshipGrey()
|
||||
}
|
||||
|
||||
@ -277,14 +296,14 @@ import UIKit
|
||||
// MARK: - Constraint Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setLeftPinConstant(_ constant: CGFloat) {
|
||||
@objc open override func setLeftPinConstant(_ constant: CGFloat) {
|
||||
|
||||
entryContainerLeading?.constant = constant
|
||||
feedbackLabelLeading?.constant = constant
|
||||
titleLabelLeading?.constant = constant
|
||||
}
|
||||
|
||||
open override func setRightPinConstant(_ constant: CGFloat) {
|
||||
@objc open override func setRightPinConstant(_ constant: CGFloat) {
|
||||
|
||||
entryContainerTrailing?.constant = constant
|
||||
feedbackLabelTrailing?.constant = constant
|
||||
@ -295,7 +314,7 @@ import UIKit
|
||||
// MARK: - Molecular
|
||||
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)
|
||||
self.delegateObject = delegateObject
|
||||
|
||||
@ -303,7 +322,7 @@ extension EntryField {
|
||||
|
||||
entryContainer.setWithJSON(dictionary, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
if let titleText = dictionary["title"] as? String {
|
||||
if let titleText = dictionary[KeyTitle] as? String {
|
||||
title = titleText
|
||||
}
|
||||
|
||||
@ -319,13 +338,17 @@ extension EntryField {
|
||||
self.isLocked = isLocked
|
||||
}
|
||||
|
||||
if let isSelected = dictionary["isSelected"] as? Bool {
|
||||
self.isSelected = isSelected
|
||||
}
|
||||
|
||||
// Key used to send text value to server
|
||||
if let fieldKey = dictionary[KeyFieldKey] as? String {
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -333,15 +356,15 @@ extension EntryField {
|
||||
// MARK: - Form Validation
|
||||
extension EntryField: FormValidationProtocol {
|
||||
|
||||
public func isValidField() -> Bool {
|
||||
@objc public func isValidField() -> Bool {
|
||||
return isValid
|
||||
}
|
||||
|
||||
public func formFieldName() -> String? {
|
||||
@objc public func formFieldName() -> String? {
|
||||
return fieldKey
|
||||
}
|
||||
|
||||
public func formFieldValue() -> Any? {
|
||||
@objc public func formFieldValue() -> Any? {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
open class ItemDropdownEntryField: DropdownEntryField {
|
||||
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -19,59 +19,49 @@ open class ItemDropdownEntryField: DropdownEntryField {
|
||||
|
||||
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
|
||||
|
||||
//--------------------------------------------------
|
||||
// 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
|
||||
//--------------------------------------------------
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
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.pickerData = pickerData
|
||||
setup()
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
|
||||
pickerView = MVMCoreUICommonViewsUtility.addPicker(to: textField, delegate: self)
|
||||
textField.hideBlinkingCaret = true
|
||||
uiTextFieldDelegate = self
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
fatalError("ItemDropdownEntryField init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// 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?.dataSource = delegate
|
||||
}
|
||||
|
||||
private func setInitialValueFromPicker() {
|
||||
@objc private func setInitialValueFromPicker() {
|
||||
|
||||
if setInitialValueInTextField, let pickerIndex = pickerView?.selectedRow(inComponent: 0) {
|
||||
text = pickerData[pickerIndex]
|
||||
@ -88,19 +78,19 @@ open class ItemDropdownEntryField: DropdownEntryField {
|
||||
// MARK:- Base Picker Delegate
|
||||
extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
||||
|
||||
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
@objc public func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
return componentsCount
|
||||
}
|
||||
|
||||
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
@objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||
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]
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
@ -108,7 +98,7 @@ extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
||||
// MARK: - Molecular
|
||||
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)
|
||||
|
||||
guard let dictionary = json, !dictionary.isEmpty else { return }
|
||||
@ -119,20 +109,10 @@ extension ItemDropdownEntryField {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITextField Intercept
|
||||
// MARK: - Accessibility
|
||||
extension ItemDropdownEntryField {
|
||||
|
||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
|
||||
setInitialValueFromPicker()
|
||||
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
extension DropdownEntryField {
|
||||
|
||||
open override func setAccessibilityString(_ accessibilityString: String?) {
|
||||
@objc open override func setAccessibilityString(_ accessibilityString: String?) {
|
||||
|
||||
var accessibilityString = accessibilityString ?? ""
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ import MVMCore
|
||||
*/
|
||||
@objcMembers open class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
// MARK: - Stored Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var isNationalMDN = true
|
||||
@ -30,7 +30,7 @@ import MVMCore
|
||||
private weak var proprietorTextDelegate: UITextFieldDelegate?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Formats the MDN when setting and removes format of MDN when reading.
|
||||
@ -52,21 +52,15 @@ import MVMCore
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
@objc public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates.
|
||||
public override init(bothDelegates: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||
super.init(frame: .zero)
|
||||
setBothTextDelegates(to: bothDelegates)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("MdnEntryField xib not supported.")
|
||||
}
|
||||
@ -75,7 +69,7 @@ import MVMCore
|
||||
// MARK: - Setup
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setupFieldContainerContent(_ container: UIView) {
|
||||
@objc public override func setupFieldContainerContent(_ container: UIView) {
|
||||
super.setupFieldContainerContent(container)
|
||||
|
||||
textField.keyboardType = .numberPad
|
||||
@ -92,7 +86,7 @@ import MVMCore
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func hasValidMDN() -> Bool {
|
||||
@objc public func hasValidMDN() -> Bool {
|
||||
|
||||
guard let MDN = mdn, !MDN.isEmpty else { return true }
|
||||
|
||||
@ -103,13 +97,13 @@ import MVMCore
|
||||
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
|
||||
}
|
||||
|
||||
public func validateAndColor() -> Bool {
|
||||
@objc public func validateAndColor() -> Bool {
|
||||
|
||||
if !shouldValidateMDN {
|
||||
let isValid = hasValidMDN()
|
||||
|
||||
if isValid {
|
||||
clearErrorState()
|
||||
showError = false
|
||||
} else {
|
||||
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||
showError = true
|
||||
@ -136,7 +130,7 @@ import MVMCore
|
||||
// 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 {
|
||||
|
||||
@ -163,14 +157,14 @@ import MVMCore
|
||||
// MARK: - Implemented TextField Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
|
||||
textField.resignFirstResponder()
|
||||
|
||||
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) {
|
||||
return false
|
||||
@ -179,13 +173,13 @@ import MVMCore
|
||||
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)
|
||||
proprietorTextDelegate?.textFieldDidBeginEditing?(textField)
|
||||
}
|
||||
|
||||
public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
|
||||
|
||||
@ -194,21 +188,17 @@ import MVMCore
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Passed Along TextField delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
|
||||
return proprietorTextDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
}
|
||||
|
||||
@ -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.
|
||||
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 {
|
||||
didSet {
|
||||
get { return super.isEnabled }
|
||||
set (enabled) {
|
||||
super.isEnabled = enabled
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.textField.isEnabled = self.isEnabled
|
||||
self.textField.textColor = self.isEnabled ? self.textColor.enabled : self.textColor.disabled
|
||||
self.textField.isEnabled = enabled
|
||||
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? {
|
||||
get { return textField.text }
|
||||
set {
|
||||
@ -74,6 +85,10 @@ import UIKit
|
||||
set { textField.placeholder = newValue }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
public var validationBlock: ((_ value: String?) -> Bool)? {
|
||||
didSet { valueChanged() }
|
||||
}
|
||||
@ -122,21 +137,15 @@ import UIKit
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
@objc public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates.
|
||||
public init(bothDelegates: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||
super.init(frame: .zero)
|
||||
setBothTextDelegates(to: bothDelegates)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("TextEntryField does not support xib.")
|
||||
}
|
||||
@ -145,7 +154,7 @@ import UIKit
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setupFieldContainerContent(_ container: UIView) {
|
||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||
|
||||
MFStyler.styleTextField(textField)
|
||||
container.addSubview(textField)
|
||||
@ -162,42 +171,28 @@ import UIKit
|
||||
accessibilityElements = [titleLabel, textField, feedbackLabel]
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
@objc open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
MFStyler.styleTextField(textField)
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
deinit {
|
||||
@objc deinit {
|
||||
setBothTextDelegates(to: nil)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
open func clearErrorState() {
|
||||
|
||||
textField.accessibilityValue = nil
|
||||
feedback = nil
|
||||
showError = false
|
||||
}
|
||||
|
||||
public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||
@objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) {
|
||||
|
||||
observingTextFieldDelegate = delegate
|
||||
uiTextFieldDelegate = delegate
|
||||
}
|
||||
|
||||
public func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
return (enteredValue?.count ?? 0) > 0
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing for Change (TextFieldDelegate)
|
||||
//--------------------------------------------------
|
||||
|
||||
override open func resignFirstResponder() -> Bool {
|
||||
@objc override open func resignFirstResponder() -> Bool {
|
||||
|
||||
textField.resignFirstResponder()
|
||||
isSelected = false
|
||||
@ -209,10 +204,14 @@ import UIKit
|
||||
_ = self.resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing for Change (TextFieldDelegate)
|
||||
//--------------------------------------------------
|
||||
public func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
return (enteredValue?.count ?? 0) > 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidChangeNotification
|
||||
@objc func valueChanged() {
|
||||
|
||||
if !showError {
|
||||
@ -225,19 +224,20 @@ import UIKit
|
||||
isValid = validationBlock?(text) ?? true
|
||||
|
||||
if previousValidity && !isValid {
|
||||
feedback = errorMessage
|
||||
showError = true
|
||||
observingTextFieldDelegate?.isInvalid?(textfield: self)
|
||||
|
||||
} else if !previousValidity && isValid {
|
||||
clearErrorState()
|
||||
showError = false
|
||||
observingTextFieldDelegate?.isValid?(textfield: self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidEndEditingNotification
|
||||
@objc func endInputing() {
|
||||
|
||||
if isValid {
|
||||
clearErrorState()
|
||||
showError = false
|
||||
entryContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
|
||||
} else if let errMessage = errorMessage {
|
||||
@ -245,6 +245,7 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidBeginEditingNotification
|
||||
@objc func startEditing() {
|
||||
|
||||
isSelected = true
|
||||
@ -255,7 +256,7 @@ import UIKit
|
||||
// MARK: - Molecular
|
||||
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)
|
||||
|
||||
guard let delegateObject = delegateObject,
|
||||
@ -306,7 +307,7 @@ extension TextEntryField {
|
||||
}
|
||||
|
||||
if let formValidationProtocol = delegateObject.formValidationProtocol {
|
||||
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol) as? ObservingTextFieldDelegate
|
||||
observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
|
||||
}
|
||||
|
||||
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
|
||||
@ -317,7 +318,7 @@ extension TextEntryField {
|
||||
// MARK: - Accessibility
|
||||
extension TextEntryField {
|
||||
|
||||
open override func pushAccessibilityNotification() {
|
||||
@objc open override func pushAccessibilityNotification() {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
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 ?? ""
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
public var direction: Direction = .right
|
||||
public var size: CaretSize?
|
||||
|
||||
|
||||
public var enabledColor: UIColor = .black
|
||||
public var disabledColor: UIColor = .mfSilver()
|
||||
|
||||
@ -48,17 +48,17 @@
|
||||
case vertical
|
||||
case horizontal
|
||||
}
|
||||
|
||||
// Dimensions of container; provided by InVision.
|
||||
|
||||
// Dimensions of container; provided by InVision design.
|
||||
func dimensions() -> CGSize {
|
||||
|
||||
|
||||
switch self {
|
||||
case .small(let o):
|
||||
return o == .vertical ? CGSize(width: 6, height: 10) : CGSize(width: 10, height: 6)
|
||||
|
||||
case .medium(let o):
|
||||
return o == .vertical ? CGSize(width: 9, height: 16) : CGSize(width: 16, height: 9)
|
||||
|
||||
|
||||
case .large(let o):
|
||||
return o == .vertical ? CGSize(width: 14, height: 24) : CGSize(width: 24, height: 14)
|
||||
}
|
||||
@ -114,7 +114,7 @@
|
||||
caretPath.removeAllPoints()
|
||||
caretPath.lineJoinStyle = .miter
|
||||
caretPath.lineWidth = lineWidth
|
||||
|
||||
|
||||
let inset = lineWidth / 2
|
||||
let halfWidth = frame.size.width / 2
|
||||
let halfHeight = frame.size.height / 2
|
||||
@ -168,7 +168,7 @@
|
||||
@objc public func setConstraints() {
|
||||
|
||||
guard let dimensions = size?.dimensions() else { return }
|
||||
|
||||
|
||||
heightAnchor.constraint(equalToConstant: dimensions.height).isActive = true
|
||||
widthAnchor.constraint(equalToConstant: dimensions.width).isActive = true
|
||||
}
|
||||
@ -191,16 +191,16 @@
|
||||
strokeColor = UIColor.mfGet(forHex: strokeColorHex)
|
||||
}
|
||||
|
||||
if let isHiddenValue = dictionary[KeyIsHidden] as? Bool {
|
||||
isHidden = isHiddenValue
|
||||
if let isHidden = dictionary[KeyIsHidden] as? Bool {
|
||||
self.isHidden = isHidden
|
||||
}
|
||||
|
||||
if let isOpaqueValue = dictionary[KeyIsOpaque] as? Bool {
|
||||
isOpaque = isOpaqueValue
|
||||
if let isOpaque = dictionary[KeyIsOpaque] as? Bool {
|
||||
self.isOpaque = isOpaque
|
||||
}
|
||||
|
||||
if let lineWidthValue = dictionary["lineWidth"] as? CGFloat {
|
||||
lineWidth = lineWidthValue
|
||||
if let lineWidth = dictionary["lineWidth"] as? CGFloat {
|
||||
self.lineWidth = lineWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ open class TextField: UITextField {
|
||||
// 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?
|
||||
|
||||
|
||||
@ -23,14 +23,23 @@ import UIKit
|
||||
return layer
|
||||
}()
|
||||
|
||||
/// Total control over bottom bar and the drawn borders.
|
||||
public var disableBorders = false {
|
||||
/// Total control overthe drawn top,bottom, left and right borders.
|
||||
public var disableAllBorders = false {
|
||||
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
|
||||
|
||||
public var borderStrokeColor: UIColor = .mfSilver()
|
||||
@ -40,27 +49,60 @@ import UIKit
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
public var showError = false {
|
||||
didSet {
|
||||
showError ? errorUI() : originalUI()
|
||||
private var _isEnabled: Bool = true
|
||||
private var _showError: Bool = false
|
||||
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 {
|
||||
didSet {
|
||||
isEnabled ? originalUI() : disabledUI()
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isEnabled = true
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
|
||||
fieldState = error ? .error : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isLocked = false {
|
||||
didSet {
|
||||
isLocked ? lockedUI() : originalUI()
|
||||
public var isLocked: Bool {
|
||||
get { return _isLocked }
|
||||
set (locked) {
|
||||
|
||||
_isLocked = locked
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = locked ? .locked : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isSelected = false {
|
||||
didSet {
|
||||
isSelected ? selectedUI() : originalUI()
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isLocked = false
|
||||
_isEnabled = true
|
||||
_showError = false
|
||||
|
||||
fieldState = selected ? .selected : .original
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +135,7 @@ import UIKit
|
||||
|
||||
borderPath.removeAllPoints()
|
||||
|
||||
if !disableBorders && !hideBorders {
|
||||
if !disableAllBorders && !hideBorders {
|
||||
// Brings the other half of the line inside the view to prevent cropping.
|
||||
let origin = bounds.origin
|
||||
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
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum State {
|
||||
public enum FieldState {
|
||||
case original
|
||||
case error
|
||||
case selected
|
||||
@ -162,8 +215,8 @@ import UIKit
|
||||
open func errorUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
borderStrokeColor = .mfPumpkin()
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfPumpkin()
|
||||
bottomBar?.backgroundColor = UIColor.mfPumpkin().cgColor
|
||||
refreshUI(bottomBarSize: 4)
|
||||
}
|
||||
@ -171,8 +224,8 @@ import UIKit
|
||||
open func selectedUI() {
|
||||
|
||||
isUserInteractionEnabled = true
|
||||
borderStrokeColor = .black
|
||||
hideBorders = false
|
||||
borderStrokeColor = .black
|
||||
bottomBar?.backgroundColor = UIColor.black.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
@ -180,8 +233,8 @@ import UIKit
|
||||
open func lockedUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
borderStrokeColor = .clear
|
||||
hideBorders = true
|
||||
borderStrokeColor = .clear
|
||||
bottomBar?.backgroundColor = UIColor.clear.cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
@ -189,15 +242,15 @@ import UIKit
|
||||
open func disabledUI() {
|
||||
|
||||
isUserInteractionEnabled = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
hideBorders = false
|
||||
borderStrokeColor = .mfSilver()
|
||||
bottomBar?.backgroundColor = UIColor.mfSilver().cgColor
|
||||
refreshUI(bottomBarSize: 1)
|
||||
}
|
||||
|
||||
open func refreshUI(bottomBarSize: CGFloat? = nil) {
|
||||
|
||||
if !disableBorders {
|
||||
if !disableAllBorders {
|
||||
let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1)
|
||||
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 }
|
||||
|
||||
if let disableBorders = dictionary["disableBorders"] as? Bool {
|
||||
self.disableBorders = disableBorders
|
||||
if let disableAllBorders = dictionary["disableAllBorders"] as? Bool {
|
||||
self.disableAllBorders = disableAllBorders
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,8 +38,9 @@
|
||||
@"caretButton": CaretButton.class,
|
||||
@"textField": TextEntryField.class,
|
||||
@"digitEntryField": DigitEntryField.class,
|
||||
@"itemDropdownEntryField": ItemDropdownEntryField.class,
|
||||
@"dateDropdownEntryField": DateDropdownEntryField.class,
|
||||
@"mdnEntryField" : MdnEntryField.class,
|
||||
@"dropdownEntryField" : DropdownEntryField.class,
|
||||
@"checkbox" : Checkbox.class,
|
||||
@"checkboxWithLabel" : CheckboxWithLabelView.class,
|
||||
@"cornerLabels" : CornerLabels.class,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user