latest. no errs.
This commit is contained in:
parent
15c2050c4e
commit
70a3ad2804
@ -23,7 +23,7 @@ import UIKit
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
weak var textBoxDelegate: DigitTextBoxDelegate?
|
||||
weak var textBoxDelegate: DigitBoxDelegate?
|
||||
|
||||
private var previousSize: CGFloat = 0.0
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
open class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -24,58 +24,68 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
private var switchedAutomatically = false
|
||||
public var digitFields: [DigitBox]?
|
||||
|
||||
/// Setgs placeholder text in the textField.
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
if isEnabled {
|
||||
descriptionLabel?.styleB2(true)
|
||||
} else {
|
||||
descriptionLabel?.textColor = UIColor.mfBattleshipGrey()
|
||||
}
|
||||
|
||||
for textField in digitFields ?? [] {
|
||||
textField.isUserInteractionEnabled = isEnabled
|
||||
textField.isEnabled = isEnabled
|
||||
textField.textColor = isEnabled ? .black : UIColor.mfBattleshipGrey()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets placeholder text in the textField.
|
||||
public override var feedback: String? {
|
||||
get {
|
||||
var string = ""
|
||||
|
||||
for digitField in digitFields ?? [] {
|
||||
if let placeholderText = digitField.attributedPlaceholder?.string {
|
||||
string += placeholderText
|
||||
if let digitext = digitField.attributedPlaceholder?.string {
|
||||
string += digitext
|
||||
}
|
||||
}
|
||||
|
||||
return !string.isEmpty ? string : nil
|
||||
}
|
||||
set {
|
||||
guard let placeholderValue = newValue else { return }
|
||||
guard let fieldValue = newValue, let fields = digitFields else { return }
|
||||
|
||||
|
||||
|
||||
(digitFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
|
||||
if idx < (newValue?.count ?? 0) {
|
||||
|
||||
let stringForIndex = (newValue as NSString?)?.substring(with: NSRange(location: idx, length: 1))
|
||||
obj.attributedPlaceholder = NSAttributedString(string: stringForIndex ?? "", attributes: [
|
||||
for (index, field) in fields.enumerated() {
|
||||
if index < fieldValue.count {
|
||||
let stringForIndex = (newValue as NSString?)?.substring(with: NSRange(location: index, length: 1))
|
||||
field.attributedPlaceholder = NSAttributedString(string: stringForIndex ?? "", attributes: [
|
||||
NSAttributedString.Key.foregroundColor: UIColor.mfBattleshipGrey()])
|
||||
} else if stop != nil {
|
||||
stop = true
|
||||
}
|
||||
})
|
||||
}
|
||||
//
|
||||
// if feedback.text.length > 0 {
|
||||
// labelToTextFieldPin?.constant = 10
|
||||
// } else {
|
||||
// labelToTextFieldPin?.constant = 0
|
||||
// }
|
||||
|
||||
// adding missing accessibilityLabel value
|
||||
// if we have some value in accessibilityLabel,
|
||||
// then only can append regular and picker item
|
||||
// textField.accessibilityLabel() = newValue ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "mfdigittextfield_regular"))
|
||||
//
|
||||
// super.showErrorMessage(errorMessage)
|
||||
//
|
||||
// if self.showErrorMessage {
|
||||
// self.labelToTextFieldPin?.constant = 10
|
||||
// }
|
||||
// for field in self.digitFields ?? [] {
|
||||
// field.setAsError()
|
||||
// }
|
||||
}
|
||||
|
||||
// If there is already text in the textfield, set the place holder label below.
|
||||
if placeholderErrorLabel.length > 0 && !showError {
|
||||
placeholderErrorLabel.text = newValue
|
||||
|
||||
} else if !showError {
|
||||
placeholderErrorLabel.text = ""
|
||||
}
|
||||
|
||||
if label.text.length > 0 {
|
||||
labelToTextFieldPin?.constant = 10
|
||||
} else {
|
||||
labelToTextFieldPin?.constant = 0
|
||||
}
|
||||
|
||||
// adding missing accessibilityLabel value
|
||||
// if we have some value in accessibilityLabel,
|
||||
// then only can append regular and picker item
|
||||
textField.accessibilityLabel() = newValue ?? "" + (MVMCoreUIUtility.hardcodedString(withKey: "mfdigittextfield_regular"))
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override var text: String? {
|
||||
get {
|
||||
var string = ""
|
||||
@ -89,30 +99,42 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
return string
|
||||
}
|
||||
set {
|
||||
(digitFields as NSArray?)?.enumerateObjects( { obj, idx, stop in
|
||||
|
||||
if idx < (text?.count ?? 0) {
|
||||
let stringForIndex = (text as NSString?)?.substring(with: NSRange(location: idx, length: 1))
|
||||
obj.text = stringForIndex
|
||||
} else if stop != nil {
|
||||
stop = true
|
||||
guard let fields = self.digitFields else { return }
|
||||
|
||||
for (index, field) in fields.enumerated() {
|
||||
if index < (text?.count ?? 0) {
|
||||
let stringForIndex = (text as NSString?)?.substring(with: NSRange(location: index, length: 1))
|
||||
field.text = stringForIndex
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
valueChanged()
|
||||
}
|
||||
}
|
||||
|
||||
public override var formText: String? {
|
||||
get {
|
||||
return formDescriptionLabel?.text
|
||||
}
|
||||
public override var descriptionText: String? {
|
||||
get { return descriptionLabel?.text }
|
||||
set {
|
||||
if let formText = newValue, !formText.isEmpty > 0 {
|
||||
if let formText = newValue, !formText.isEmpty {
|
||||
messageToTextFieldPin?.constant = 10
|
||||
} else {
|
||||
messageToTextFieldPin?.constant = 0
|
||||
}
|
||||
super.formText = newValue
|
||||
super.descriptionText = newValue
|
||||
}
|
||||
}
|
||||
|
||||
public override var errorMessage: String? {
|
||||
didSet {
|
||||
if let errorMessage = errorMessage, !errorMessage.isEmpty {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
for field in self.digitFields ?? [] {
|
||||
field.hideError()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +157,7 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
public init(numberOfDigits: Int) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
setup()
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
}
|
||||
@ -142,29 +165,66 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
public init(numberOfDigits: Int, bothDelegates delegates: (UITextFieldDelegate & MFTextFieldDelegate)?) {
|
||||
super.init(bothDelegates: delegates as? (TextFieldDelegate & UITextFieldDelegate))
|
||||
|
||||
setup()
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
}
|
||||
|
||||
public init(withNumberOfDigits numberOfDigits: Int, withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?, size: CGFloat) {
|
||||
public init(numberOfDigits: Int, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?, size: CGFloat) {
|
||||
super.init(bothDelegates: delegate as? (TextFieldDelegate & UITextFieldDelegate))
|
||||
|
||||
setup()
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: size)
|
||||
}
|
||||
|
||||
open override func setupFieldContainerContent(_ container: UIView) {
|
||||
|
||||
setupTextFieldsView(forSize: numberOfDigits)
|
||||
setupTextFieldsView(forSize: CGFloat(numberOfDigits))
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open func setup() {
|
||||
|
||||
descriptionLabel?.styleB2(true)
|
||||
descriptionText = ""
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.descriptionLabel?.updateView(size)
|
||||
|
||||
if let digitFields = self.digitFields, !digitFields.isEmpty {
|
||||
|
||||
// Remove all current UI.
|
||||
StackableViewController.remove(digitFields)
|
||||
|
||||
// Update text boxes.
|
||||
for digitField in digitFields {
|
||||
digitField.updateView(size)
|
||||
}
|
||||
}
|
||||
|
||||
// Layout text boxes.
|
||||
self.setupTextFieldsView(forSize: size)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
func createDigitField() -> DigitTextBox {
|
||||
func createDigitField() -> DigitBox {
|
||||
|
||||
let textField = DigitTextBox()
|
||||
let textField = DigitBox()
|
||||
textField.delegate = self
|
||||
textField.textBoxDelegate = self
|
||||
|
||||
@ -180,7 +240,7 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
|
||||
if numberOfDigits > 0 {
|
||||
|
||||
let digitFields = [DigitTextBox](repeating: createDigitField(), count: numberOfDigits)
|
||||
let digitFields = [DigitBox](repeating: createDigitField(), count: numberOfDigits)
|
||||
|
||||
for digitField in digitFields {
|
||||
digitField.updateView(size)
|
||||
@ -200,47 +260,31 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
if let placeholder = self.placeholder, !placeholder.isEmpty {
|
||||
if let feedback = self.feedback, !feedback.isEmpty {
|
||||
self.labelToTextFieldPin?.constant = 10
|
||||
|
||||
|
||||
} else {
|
||||
self.labelToTextFieldPin?.constant = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
func setAsSecureTextEntry(_ secureEntry: Bool) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let self = self,
|
||||
let fields = self.digitFields
|
||||
else { return }
|
||||
|
||||
self.formDescriptionLabel?.updateView(size)
|
||||
|
||||
if let digitFields = self.digitFields, !digitFields.isEmpty {
|
||||
for (index, field) in fields.enumerated() {
|
||||
field.isSecureTextEntry = secureEntry
|
||||
|
||||
// Remove all current UI.
|
||||
StackableViewController.remove(digitFields)
|
||||
|
||||
// Update text boxes.
|
||||
for digitField in digitFields {
|
||||
digitField.updateView(size)
|
||||
}
|
||||
// Accessibility - 33704 fix voice over will read what pin user is filling
|
||||
field.accessibilityLabel = String(format: "PIN %lu of %lu", UInt(index) + 1, UInt(fields.count))
|
||||
}
|
||||
|
||||
// Layout text boxes.
|
||||
self.setupTextFieldsView(forSize: size)
|
||||
}
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
formDescriptionLabel?.styleB2(true)
|
||||
self.formText = ""
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
|
||||
func setupTextFieldsView(forSize size: CGFloat) {
|
||||
|
||||
guard let space = MFSizeObject(standardSize: 5, smalliPhoneSize: 3)?.getValueBasedOnScreenSize(),
|
||||
@ -269,6 +313,20 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
})
|
||||
}
|
||||
|
||||
func setDefaultValidationBlock() {
|
||||
|
||||
weak var weakSelf = self
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
|
||||
if (enteredValue?.count ?? 0) > 0 && (enteredValue?.count ?? 0) == weakSelf?.digitFields?.count {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//--------------------------------------------------
|
||||
@ -282,106 +340,21 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
numberOfDigits = digits
|
||||
}
|
||||
|
||||
if !dictionary.isEmpty{
|
||||
for textField in digitFields ?? [] {
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegateObject as? UITextFieldDelegate)
|
||||
}
|
||||
}
|
||||
|
||||
buildTextFieldsView(size: MVMCoreUIUtility.getWidth())
|
||||
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
|
||||
return 44
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Setters
|
||||
//--------------------------------------------------
|
||||
|
||||
func setAsSecureTextEntry(_ secureEntry: Bool) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
(self.digitFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
obj.isSecureTextEntry = secureEntry
|
||||
|
||||
//accessibility - 33704 fix voice over will read what pin user is filling
|
||||
obj.accessibilityLabel() = String(format: "PIN %lu of %lu", UInt(idx) + 1, UInt(self.digitFields?.count ?? 0))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func showErrorMessage(_ errorMessage: String?) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
super.showErrorMessage (errorMessage)
|
||||
|
||||
if self.showError {
|
||||
self.labelToTextFieldPin?.constant = 10
|
||||
}
|
||||
for field in self.digitFields ?? [] {
|
||||
field.setAsError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override func hideError() {
|
||||
super.hideError()
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
for field in self.digitFields ?? [] {
|
||||
field.hideError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setWithMap(_ map: [AnyHashable : Any]?, bothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?) {
|
||||
super.setWithMap(map, bothDelegates: delegate as? (TextFieldDelegate & UITextFieldDelegate))
|
||||
|
||||
if (map?.count ?? 0) > 0 {
|
||||
for textField in digitFields ?? [] {
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setDefaultValidationBlock() {
|
||||
|
||||
weak var weakSelf = self
|
||||
|
||||
self.validationBlock = { enteredValue in
|
||||
if (enteredValue?.count ?? 0) > 0 && (enteredValue?.count ?? 0) == weakSelf?.digitFields?.count {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func enable(_ enable: Bool) {
|
||||
super.enable(enable)
|
||||
|
||||
if enable {
|
||||
formDescriptionLabel?.styleB2(true)
|
||||
} else {
|
||||
formDescriptionLabel?.textColor = UIColor.mfBattleshipGrey()
|
||||
}
|
||||
|
||||
for textField in digitFields ?? [] {
|
||||
textField.isUserInteractionEnabled = enable
|
||||
textField.isEnabled = enable
|
||||
|
||||
if enable {
|
||||
textField.textColor = UIColor.black
|
||||
} else {
|
||||
textField.textColor = UIColor.mfBattleshipGrey()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Helpers
|
||||
//--------------------------------------------------
|
||||
@ -390,56 +363,58 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
|
||||
var selectNextField = false
|
||||
|
||||
(digitFields as NSArray?)?.enumerateObjects(options: .reverse, using: { obj, idx, stop in
|
||||
if obj == currentTextField {
|
||||
guard let fields = digitFields else { return }
|
||||
|
||||
for field in fields {
|
||||
|
||||
if field == currentTextField {
|
||||
selectNextField = true
|
||||
|
||||
} else if selectNextField {
|
||||
if !clear {
|
||||
self.switchedAutomatically = true
|
||||
switchedAutomatically = true
|
||||
}
|
||||
obj.becomeFirstResponder()
|
||||
self.switchedAutomatically = false
|
||||
stop = true
|
||||
field.becomeFirstResponder()
|
||||
switchedAutomatically = false
|
||||
|
||||
//accessibility
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: obj)
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: field)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func selectNextTextField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectNextField = false
|
||||
(digitFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
|
||||
if obj == currentTextField {
|
||||
|
||||
guard let fields = digitFields else { return }
|
||||
|
||||
for field in fields{
|
||||
if field == currentTextField {
|
||||
selectNextField = true
|
||||
|
||||
} else if selectNextField {
|
||||
if !clear {
|
||||
self.switchedAutomatically = true
|
||||
}
|
||||
obj.becomeFirstResponder()
|
||||
field.becomeFirstResponder()
|
||||
self.switchedAutomatically = false
|
||||
stop = true
|
||||
|
||||
//accessibility
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: obj)
|
||||
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: field)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Accessinility
|
||||
//--------------------------------------------------
|
||||
|
||||
open override var accessibilityElements: [Any]? {
|
||||
|
||||
if let digitFields = self.digitFields {
|
||||
return [digitFields] //return [self.digitFields arrayByAddingObject:(DigitTextBox *)self.label];
|
||||
} else {
|
||||
return [placeholder]
|
||||
}
|
||||
open override class func accessibilityElements() -> [Any]? {
|
||||
// self.digit
|
||||
// if let digitFields = self.digitFields {
|
||||
// return [digitFields] + [textField]
|
||||
// }
|
||||
//
|
||||
return [textField]
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -464,9 +439,9 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
let oldLength = textField.text?.count ?? 0
|
||||
let replacementLength = string.count
|
||||
if replacementLength > 1 {
|
||||
|
||||
// Too long (Check with AKQA if they want to allow pasting the digits.
|
||||
return false
|
||||
|
||||
} else if replacementLength == 1 && (oldLength == 1 || oldLength == 0) {
|
||||
|
||||
// One character, switch old value with new, select next textfield
|
||||
@ -474,21 +449,23 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
selectNextTextField(textField, clear: false)
|
||||
valueChanged()
|
||||
return false
|
||||
|
||||
} else if replacementLength == 0 && oldLength == 1 {
|
||||
// non empty cell, clear and stay.
|
||||
textField.text = ""
|
||||
valueChanged()
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return false
|
||||
}
|
||||
|
||||
func textFieldDidDelete(_ textField: UITextField?) {
|
||||
|
||||
// empty cell, go back to previous cell and clear.
|
||||
// Empty cell, go back to previous cell and clear.
|
||||
selectPreviousTextField(textField, clear: true)
|
||||
}
|
||||
|
||||
@ -504,7 +481,6 @@ class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
|
||||
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
|
||||
uiTextFieldDelegate?.textFieldDidEndEditing?(textField)
|
||||
}
|
||||
|
||||
|
||||
@ -21,21 +21,11 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public var dropDownCaretLabel: UILabel?
|
||||
|
||||
private var borderPath: UIBezierPath?
|
||||
public var dropDownIsDisplayed = false
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
didSet {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// The text of this textField.
|
||||
public override var text: String? {
|
||||
get { return textField?.text }
|
||||
set {
|
||||
textField?.text = newValue
|
||||
valueChanged()
|
||||
showDropDown(isEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,8 +57,11 @@ import UIKit
|
||||
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates.
|
||||
public override init(bothDelegates: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
setBothTextFieldDelegates(bothDelegates)
|
||||
|
||||
if let textField = textField {
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: bothDelegates)
|
||||
}
|
||||
setBothTextDelegates(bothDelegates)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -76,7 +69,9 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setupFieldContainerContent(_ container: UIView) {
|
||||
|
||||
|
||||
guard let textField = textField else { return }
|
||||
|
||||
let dropDownCaretLabel = Label()
|
||||
self.dropDownCaretLabel = dropDownCaretLabel
|
||||
dropDownCaretLabel.setContentHuggingPriority(UILayoutPriority(900), for: .horizontal)
|
||||
@ -97,169 +92,26 @@ import UIKit
|
||||
dropDownCaretWidth?.isActive = true
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func showDropDown(_ show: Bool) {
|
||||
|
||||
if hasDropDown {
|
||||
dropDownCaretLabel?.isHidden = !show
|
||||
dropDownCarrotWidth?.isActive = !show
|
||||
setNeedsLayout()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
open override func showErrorMessage(_ errorMessage: String?) {
|
||||
super.showErrorMessage(errorMessage)
|
||||
|
||||
textField?.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textfield_error_message") ?? "", textField?.text ?? "", errorMessage ?? "")
|
||||
}
|
||||
|
||||
open override func hideError() {
|
||||
super.hideError()
|
||||
|
||||
textField?.accessibilityValue = nil
|
||||
}
|
||||
|
||||
public func setBothTextFieldDelegates(_ delegate: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
|
||||
mfTextFieldDelegate = delegate
|
||||
uiTextFieldDelegate = delegate
|
||||
}
|
||||
|
||||
public override func setWithMap(_ map: [AnyHashable: Any]?) {
|
||||
super.setWithMap(map)
|
||||
|
||||
guard let map = map, !map.isEmpty else { return }
|
||||
|
||||
if let formText = map[KeyLabel] as? String {
|
||||
self.formText = formText
|
||||
}
|
||||
|
||||
if let text = map[KeyValue] as? String {
|
||||
self.text = text
|
||||
}
|
||||
|
||||
if let text = map[KeyDisable] as? String, text.isEqual(StringY) || map.boolForKey(KeyDisable) {
|
||||
formIsDisabled()
|
||||
}
|
||||
|
||||
if let dropDown = map[KeyType] as? String {
|
||||
dropDownCaretLabel?.isHidden = false
|
||||
self.hasDropDown = true
|
||||
}
|
||||
|
||||
// Key used to send text value to server
|
||||
if let fieldKey = map[KeyFieldKey] as? String {
|
||||
self.fieldKey = fieldKey
|
||||
}
|
||||
|
||||
switch map.stringForkey(KeyType) {
|
||||
case "dropDown":
|
||||
dropDownCaretLabel?.isHidden = false
|
||||
self.hasDropDown = true
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let regex = map.stringForkey("regex")
|
||||
|
||||
if !regex.isEmpty {
|
||||
validationBlock = { enteredValue in
|
||||
guard let value = enteredValue else { return false }
|
||||
return MVMCoreUIUtility.validate(value, withRegularExpression: regex)
|
||||
}
|
||||
} else {
|
||||
defaultValidationBlock()
|
||||
}
|
||||
}
|
||||
|
||||
public func setWithMap(_ map: [AnyHashable: Any]?, bothDelegates delegate: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
|
||||
guard let textField = textField else { return }
|
||||
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegate)
|
||||
setBothTextFieldDelegates(delegate)
|
||||
setWithMap(map)
|
||||
}
|
||||
|
||||
public func defaultValidationBlock() {
|
||||
|
||||
validationBlock = { enteredValue in
|
||||
return (enteredValue?.count ?? 0) > 0
|
||||
}
|
||||
}
|
||||
|
||||
open override func formIsEnabled() {
|
||||
super.formIsEnabled()
|
||||
|
||||
textField?.isUserInteractionEnabled = true
|
||||
textField?.isEnabled = true
|
||||
showDropDown(true)
|
||||
}
|
||||
|
||||
open override func formIsDisabled() {
|
||||
super.formIsDisabled()
|
||||
|
||||
textField?.isUserInteractionEnabled = false
|
||||
textField?.isEnabled = false
|
||||
self.showDropDown(false)
|
||||
dropDownCaretLabel?.isHidden = !show
|
||||
dropDownCaretWidth?.isActive = !show
|
||||
setNeedsLayout()
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing for change
|
||||
//--------------------------------------------------
|
||||
|
||||
func valueChanged() {
|
||||
override func startEditing() {
|
||||
super.startEditing()
|
||||
|
||||
// Update label for placeholder
|
||||
if !showError {
|
||||
feedbackLabel?.text = ""
|
||||
}
|
||||
|
||||
let previousValidity = isValid
|
||||
|
||||
// If validation not set, input will always be valid
|
||||
isValid = validationBlock?(text) ?? true
|
||||
|
||||
if previousValidity && !isValid {
|
||||
if let errMessage = errorMessage {
|
||||
showErrorMessage(errMessage)
|
||||
}
|
||||
|
||||
if let mfTextFieldDelegate = mfTextFieldDelegate {
|
||||
mfTextFieldDelegate.isInvalid?(textfield: self)
|
||||
}
|
||||
} else if !previousValidity && isValid {
|
||||
hideError()
|
||||
|
||||
if let mfTextFieldDelegate = mfTextFieldDelegate {
|
||||
mfTextFieldDelegate.isValid?(textfield: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func endInputing() {
|
||||
|
||||
if isValid {
|
||||
hideError()
|
||||
separatorView?.backgroundColor = .black
|
||||
} else if let errMessage = errorMessage {
|
||||
showErrorMessage(errMessage)
|
||||
}
|
||||
}
|
||||
|
||||
func startEditing() {
|
||||
|
||||
textField?.becomeFirstResponder()
|
||||
showErrorDropdown(!showError)
|
||||
showDropDown(!showErrorMessage)
|
||||
}
|
||||
|
||||
class func getEnabledTextfields(_ textFieldToDetermine: [TextEntryField]?) -> [AnyHashable]? {
|
||||
@ -278,7 +130,7 @@ import UIKit
|
||||
|
||||
// MARK: - Date Picker
|
||||
extension DropdownEntryField {
|
||||
|
||||
|
||||
private func createDatePicker() {
|
||||
|
||||
guard let textField = textField else { return }
|
||||
@ -337,11 +189,6 @@ extension DropdownEntryField {
|
||||
textField?.resignFirstResponder()
|
||||
return pickedDate
|
||||
}
|
||||
|
||||
public func dismissPicker() {
|
||||
|
||||
textField?.resignFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Molecular
|
||||
@ -350,46 +197,26 @@ extension DropdownEntryField {
|
||||
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
if let delegateObject = delegateObject {
|
||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
|
||||
setWithMap(json)
|
||||
|
||||
if let formValidationProtocol = delegateObject.formValidationProtocol {
|
||||
mfTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol)
|
||||
}
|
||||
|
||||
uiTextFieldDelegate = delegateObject.uiTextFieldDelegate
|
||||
|
||||
if let textField = textField {
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate)
|
||||
}
|
||||
guard let dictionary = json,
|
||||
!dictionary.isEmpty
|
||||
else { return }
|
||||
|
||||
if let _ = dictionary[KeyType] as? String {
|
||||
dropDownCaretLabel?.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
override open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return 76
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Accessibility
|
||||
extension DropdownEntryField {
|
||||
|
||||
open override func pushAccessibilityNotification() {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: self.textField)
|
||||
}
|
||||
}
|
||||
|
||||
open override func setAccessibilityString(_ accessibilityString: String?) {
|
||||
|
||||
guard let textField = textField else { return }
|
||||
|
||||
var accessibilityString = accessibilityString ?? ""
|
||||
|
||||
if hasDropDown, let txtPickerItem = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") {
|
||||
if dropDownIsDisplayed, let txtPickerItem = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") {
|
||||
accessibilityString += txtPickerItem
|
||||
|
||||
} else if let txtRegular = MVMCoreUIUtility.hardcodedString(withKey: "textfield_regular") {
|
||||
@ -398,5 +225,4 @@ extension DropdownEntryField {
|
||||
|
||||
textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -34,14 +34,14 @@ import UIKit
|
||||
|
||||
private var borderPath: UIBezierPath?
|
||||
|
||||
public var showErrorMessage = false
|
||||
|
||||
public var errorMessage: String? {
|
||||
didSet {
|
||||
feedback = errorMessage
|
||||
}
|
||||
}
|
||||
|
||||
public var showErrorMessage = false
|
||||
|
||||
public var isEnabled = true {
|
||||
didSet {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
|
||||
Loading…
Reference in New Issue
Block a user