lztest greatest.
This commit is contained in:
parent
a5ffae9edd
commit
393b3f355b
@ -32,7 +32,7 @@
|
||||
0A21DB8C235E06EF00C160A2 /* MFDigitTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF24321E6A176003B2FB9 /* MFDigitTextField.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF24821E6A177003B2FB9 /* MFDigitTextField.m */; };
|
||||
0A21DB8E235E06EF00C160A2 /* MFDigitTextField.xib in Resources */ = {isa = PBXBuildFile; fileRef = D29DF24A21E6A177003B2FB9 /* MFDigitTextField.xib */; };
|
||||
0A21DB91235E0EDB00C160A2 /* DigitTextBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8321AE2355FE9500CB7F00 /* DigitTextBox.swift */; };
|
||||
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */; };
|
||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */; };
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
|
||||
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; };
|
||||
@ -220,9 +220,7 @@
|
||||
0A6BF4712360C56C0028F841 /* DropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropdownEntryField.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>"; };
|
||||
0A8321A72355062F00CB7F00 /* MdnTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MdnTextField.swift; sourceTree = "<group>"; };
|
||||
0A8321AC2355FC2600CB7F00 /* DigitTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitTextField.swift; sourceTree = "<group>"; };
|
||||
0A8321AE2355FE9500CB7F00 /* DigitTextBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitTextBox.swift; sourceTree = "<group>"; };
|
||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
|
||||
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
||||
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
||||
B8200E142280C4CF007245F4 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; };
|
||||
@ -764,9 +762,7 @@
|
||||
D29DF24821E6A177003B2FB9 /* MFDigitTextField.m */,
|
||||
D29DF24A21E6A177003B2FB9 /* MFDigitTextField.xib */,
|
||||
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */,
|
||||
0A8321A72355062F00CB7F00 /* MdnTextField.swift */,
|
||||
0A8321AC2355FC2600CB7F00 /* DigitTextField.swift */,
|
||||
0A8321AE2355FE9500CB7F00 /* DigitTextBox.swift */,
|
||||
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */,
|
||||
0A21DB7E235DECC500C160A2 /* FormEntryField.swift */,
|
||||
0A21DB82235DFBC500C160A2 /* MdnEntryField.swift */,
|
||||
0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */,
|
||||
@ -1053,7 +1049,7 @@
|
||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */,
|
||||
D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */,
|
||||
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
|
||||
0A21DB91235E0EDB00C160A2 /* DigitTextBox.swift in Sources */,
|
||||
0A21DB91235E0EDB00C160A2 /* DigitBox.swift in Sources */,
|
||||
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */,
|
||||
01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */,
|
||||
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// DigitTextBox.swift
|
||||
// DigitBox.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 10/15/19.
|
||||
@ -8,11 +8,11 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
@objc protocol DigitTextBoxDelegate: NSObjectProtocol {
|
||||
@objc protocol DigitBoxDelegate: NSObjectProtocol {
|
||||
@objc optional func textFieldDidDelete(_ textField: UITextField?)
|
||||
}
|
||||
|
||||
@objcMembers open class DigitTextBox: UITextField, MVMCoreViewProtocol {
|
||||
@objcMembers open class DigitBox: UITextField, MVMCoreViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -40,7 +40,7 @@ import UIKit
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
fatalError("DigitBox has not been implemented")
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@ -92,11 +92,11 @@ import UIKit
|
||||
public func updateView(_ size: CGFloat) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let wSelf = self else { return }
|
||||
guard let self = self else { return }
|
||||
|
||||
if !MVMCoreGetterUtility.fequal(a: Float(size), b: Float(wSelf.previousSize)) {
|
||||
MFStyler.styleTextField(wSelf)
|
||||
self?.font = MFFonts.mfFont55Rg(28)
|
||||
if !MVMCoreGetterUtility.fequal(a: Float(size), b: Float(self.previousSize)) {
|
||||
MFStyler.styleTextField(self)
|
||||
self.font = MFFonts.mfFont55Rg(28)
|
||||
|
||||
var digitWidth: CGFloat = 0
|
||||
var digitHeight: CGFloat = 0
|
||||
@ -115,9 +115,9 @@ import UIKit
|
||||
})
|
||||
|
||||
sizeObject?.performBlockBase(onSize: size)
|
||||
self?.widthConstraint?.constant = digitWidth
|
||||
self?.heightConstraint?.constant = digitHeight
|
||||
self?.previousSize = size
|
||||
self.widthConstraint?.constant = digitWidth
|
||||
self.heightConstraint?.constant = digitHeight
|
||||
self.previousSize = size
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
class DigitEntryField: TextEntryField, DigitTextBoxDelegate {
|
||||
class DigitEntryField: TextEntryField, DigitBoxDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -22,7 +22,7 @@ class DigitEntryField: TextEntryField, DigitTextBoxDelegate {
|
||||
|
||||
private var numberOfDigits = 0
|
||||
private var switchedAutomatically = false
|
||||
public var digitFields: [DigitTextBox]?
|
||||
public var digitFields: [DigitBox]?
|
||||
|
||||
/// Setgs placeholder text in the textField.
|
||||
public override var feedback: String? {
|
||||
|
||||
@ -1,530 +0,0 @@
|
||||
//
|
||||
// DigitTextField.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 10/15/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
@objcMembers open class DigitTextField: TextField, UITextFieldDelegate, DigitTextBoxDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
|
||||
private weak var digitFieldsView: UIView?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
private var numberOfDigits = 0
|
||||
private var switchedAutomatically = false
|
||||
public var digitFields: [DigitTextBox]?
|
||||
|
||||
/// Setgs placeholder text in the textField.
|
||||
public override var placeholder: String? {
|
||||
get {
|
||||
var string = ""
|
||||
|
||||
for digitField in digitFields ?? [] {
|
||||
if let placeholderText = digitField.attributedPlaceholder?.string {
|
||||
string += placeholderText
|
||||
}
|
||||
}
|
||||
|
||||
return !string.isEmpty ? string : nil
|
||||
}
|
||||
set {
|
||||
guard let placeholderValue = newValue 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: [
|
||||
NSAttributedString.Key.foregroundColor: UIColor.mfBattleshipGrey()])
|
||||
} else if stop != nil {
|
||||
stop = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// If there is already text in the textfield, set the place holder label below.
|
||||
if placeholderErrorLabel.length > 0 && !errorShowing {
|
||||
placeholderErrorLabel.text = newValue
|
||||
|
||||
} else if !errorShowing {
|
||||
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 = ""
|
||||
|
||||
for digitField in digitFields ?? [] {
|
||||
if let digitText = digitField.text {
|
||||
string += digitText
|
||||
}
|
||||
}
|
||||
|
||||
return string
|
||||
}
|
||||
set {
|
||||
(textFields 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
|
||||
}
|
||||
})
|
||||
valueChanged()
|
||||
}
|
||||
}
|
||||
|
||||
public override var formText: String? {
|
||||
get {
|
||||
return formLabel?.text
|
||||
}
|
||||
set {
|
||||
if let formText = newValue, !formText.isEmpty > 0 {
|
||||
messageToTextFieldPin?.constant = 10
|
||||
} else {
|
||||
messageToTextFieldPin?.constant = 0
|
||||
}
|
||||
super.formText = newValue
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
|
||||
private weak var messageToTextFieldPin: NSLayoutConstraint?
|
||||
private weak var labelToTextFieldPin: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public init(numberOfDigits: Int) {
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
}
|
||||
|
||||
public init(numberOfDigits: Int, bothDelegates delegates: (UITextFieldDelegate & MFTextFieldDelegate)?) {
|
||||
super.init(bothDelegates: delegates as? (TextFieldDelegate & UITextFieldDelegate))
|
||||
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
}
|
||||
|
||||
public init(withNumberOfDigits numberOfDigits: Int, withBothDelegates delegate: (UITextFieldDelegate & MFTextFieldDelegate)?, size: CGFloat) {
|
||||
super.init(bothDelegates: delegate as? (TextFieldDelegate & UITextFieldDelegate))
|
||||
|
||||
self.numberOfDigits = numberOfDigits
|
||||
buildTextFieldsView(size: size)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
func createDigitField() -> DigitTextBox {
|
||||
|
||||
let textField = DigitTextBox()
|
||||
textField.delegate = self
|
||||
textField.textBoxDelegate = self
|
||||
|
||||
return textField
|
||||
}
|
||||
|
||||
func buildTextFieldsView(size: CGFloat) {
|
||||
|
||||
// Remove all current UI.
|
||||
if let digitFields = digitFields, !digitFields.isEmpty {
|
||||
StackableViewController.remove(digitFields)
|
||||
}
|
||||
|
||||
if numberOfDigits > 0 {
|
||||
|
||||
let digitFields = [DigitTextBox](repeating: createDigitField(), count: numberOfDigits)
|
||||
|
||||
for digitField in digitFields {
|
||||
digitField.updateView(size)
|
||||
}
|
||||
|
||||
self.digitFields = digitFields
|
||||
setupTextFieldsView(forSize: size)
|
||||
|
||||
} else {
|
||||
digitFields = nil
|
||||
}
|
||||
}
|
||||
|
||||
func setupTextFieldsView(forSize size: CGFloat) {
|
||||
|
||||
guard let space = MFSizeObject(standardSize: 5, smalliPhoneSize: 3)?.getValueBasedOnScreenSize(),
|
||||
let digitFieldsView = digitFieldsView,
|
||||
let digitFields = digitFields
|
||||
else { return }
|
||||
|
||||
StackableViewController.populateViewHorizontally(digitFieldsView, withUIArray: digitFields, withSpacingBlock: { object in
|
||||
|
||||
var inset = UIEdgeInsets(top: 0, left: space, bottom: 0, right: space)
|
||||
|
||||
guard let digitFields = self.digitFields else { return inset }
|
||||
|
||||
if digitFields.count == 1 {
|
||||
inset.left = 0
|
||||
inset.right = 0
|
||||
|
||||
} else if let field = object as? UITextField, field == digitFields.first {
|
||||
inset.left = 0
|
||||
|
||||
} else if let field = object as? UITextField, field == digitFields.last {
|
||||
inset.right = 0
|
||||
}
|
||||
|
||||
return inset
|
||||
})
|
||||
}
|
||||
|
||||
override func valueChanged() {
|
||||
super.valueChanged()
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
if let placeholder = self.placeholder, !placeholder.isEmpty {
|
||||
self.labelToTextFieldPin?.constant = 10
|
||||
|
||||
} else {
|
||||
self.labelToTextFieldPin?.constant = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.formLabel?.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)
|
||||
}
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
formLabel?.styleB2(true)
|
||||
self.formText = ""
|
||||
alignCenterHorizontal()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
let digits = dictionary["digits"] as? Int ?? 4
|
||||
if digits != numberOfDigits {
|
||||
numberOfDigits = digits
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
(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.textFields?.count ?? 0))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override public func showErrorMessage(_ errorMessage: String?) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
super.showErrorMessage (errorMessage)
|
||||
|
||||
if self.errorShowing {
|
||||
self.labelToTextFieldPin?.constant = 10
|
||||
}
|
||||
(self.textFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
obj.setAsError()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public override func hideError() {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
|
||||
super.hideError()
|
||||
(self.textFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
obj.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 textFields ?? [] {
|
||||
MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: delegate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setDefaultValidationBlock() {
|
||||
|
||||
weak var weakSelf = self
|
||||
|
||||
self.validationBlock = { enteredValue in
|
||||
if (enteredValue?.count ?? 0) > 0 && (enteredValue?.count ?? 0) == weakSelf?.textFields?.count {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func enable(_ enable: Bool) {
|
||||
super.enable(enable)
|
||||
|
||||
if enable {
|
||||
formLabel?.styleB2(true)
|
||||
} else {
|
||||
formLabel?.textColor = UIColor.mfBattleshipGrey()
|
||||
}
|
||||
|
||||
for textField in textFields ?? [] {
|
||||
textField.isUserInteractionEnabled = enable
|
||||
textField.isEnabled = enable
|
||||
|
||||
if enable {
|
||||
textField.textColor = UIColor.black
|
||||
} else {
|
||||
textField.textColor = UIColor.mfBattleshipGrey()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Helpers
|
||||
//--------------------------------------------------
|
||||
|
||||
func selectPreviousTextField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectNextField = false
|
||||
|
||||
(textFields as NSArray?)?.enumerateObjects(options: .reverse, using: { obj, idx, stop in
|
||||
if obj == currentTextField {
|
||||
selectNextField = true
|
||||
} else if selectNextField {
|
||||
if !clear {
|
||||
self.switchedAutomatically = true
|
||||
}
|
||||
obj.becomeFirstResponder()
|
||||
self.switchedAutomatically = false
|
||||
stop = true
|
||||
|
||||
//accessibility
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func selectNextTextField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectNextField = false
|
||||
(textFields as NSArray?)?.enumerateObjects({ obj, idx, stop in
|
||||
|
||||
if obj == currentTextField {
|
||||
selectNextField = true
|
||||
|
||||
} else if selectNextField {
|
||||
if !clear {
|
||||
self.switchedAutomatically = true
|
||||
}
|
||||
obj.becomeFirstResponder()
|
||||
self.switchedAutomatically = false
|
||||
stop = true
|
||||
|
||||
//accessibility
|
||||
UIAccessibility.post(notification: .layoutChanged, argument: obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Accessinility
|
||||
//--------------------------------------------------
|
||||
|
||||
open override var accessibilityElements: [Any]? {
|
||||
|
||||
if (self.textFields) {
|
||||
return [self.textFields arrayByAddingObject:(DigitTextBox *)self.label];
|
||||
} else {
|
||||
return @[self.label];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - TextFieldDelegate
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
|
||||
if uiTextFieldDelegate!.responds(to: #selector(UITextFieldDelegate.textFieldShouldReturn(_:))) {
|
||||
return uiTextFieldDelegate!.textFieldShouldReturn!(textField)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
|
||||
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (textField.text?.count ?? 0) >= range.length + range.location {
|
||||
|
||||
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
|
||||
textField.text = string
|
||||
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
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func textFieldDidDelete(_ textField: UITextField?) {
|
||||
|
||||
// empty cell, go back to previous cell and clear.
|
||||
selectPreviousTextField(textField, clear: true)
|
||||
}
|
||||
|
||||
@objc public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
|
||||
if !switchedAutomatically {
|
||||
textField.text = ""
|
||||
valueChanged()
|
||||
}
|
||||
if (uiTextFieldDelegate?.responds(to: #selector(UITextFieldDelegate.textFieldDidBeginEditing(_:))))! {
|
||||
uiTextFieldDelegate?.textFieldDidBeginEditing!(textField)
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
if uiTextFieldDelegate!.responds(to: #selector(UITextFieldDelegate.textFieldDidEndEditing(_:))) {
|
||||
uiTextFieldDelegate!.textFieldDidEndEditing!(textField)
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
|
||||
selectPreviousTextField(textField, clear: false)
|
||||
|
||||
if uiTextFieldDelegate?.responds(to: #selector(UITextFieldDelegate.textFieldShouldClear(_:))) {
|
||||
return uiTextFieldDelegate?.textFieldShouldClear(textField)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MARK: - Passed Along TextField delegate
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
if uiTextFieldDelegate?.responds(to: #selector(UITextFieldDelegate.textFieldShouldBeginEditing(_:))) {
|
||||
return uiTextFieldDelegate?.textFieldShouldBeginEditing(textField)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
if uiTextFieldDelegate!.responds(to: #selector(UITextFieldDelegate.textFieldShouldEndEditing(_:))) {
|
||||
return uiTextFieldDelegate?.textFieldShouldEndEditing(textField)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -21,12 +21,7 @@ import UIKit
|
||||
//--------------------------------------------------
|
||||
|
||||
public var dropDownCaretLabel: UILabel?
|
||||
|
||||
public var enabledTextColor: UIColor?
|
||||
public var disabledTextColor: UIColor?
|
||||
|
||||
public var observingForChanges = false
|
||||
|
||||
|
||||
private var borderPath: UIBezierPath?
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
@ -44,12 +39,6 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
public var validationBlock: ((_ enteredValue: String?) -> Bool)? {
|
||||
didSet {
|
||||
valueChanged()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
@ -76,47 +65,18 @@ import UIKit
|
||||
}
|
||||
|
||||
/// - parameter bothDelegates: Sets both MF/UI Text Field Delegates.
|
||||
public init(bothDelegates: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
public override init(bothDelegates: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
setBothTextFieldDelegates(bothDelegates)
|
||||
}
|
||||
|
||||
/// - parameter hasDropDown: tbd
|
||||
/// - parameter map: Dictionary of values to setup this TextField
|
||||
/// - parameter bothDelegate: Sets both MF/UI Text Field Delegates.
|
||||
public init(hasDropDown: Bool = false, map: [AnyHashable: Any]?, bothDelegates: (UITextFieldDelegate & TextFieldDelegate)?) {
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
dropDownCaretLabel?.isHidden = hasDropDown
|
||||
self.hasDropDown = !hasDropDown
|
||||
setWithMap(map, bothDelegates: bothDelegates)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setupFieldContainerContent(_ container: UIView) {
|
||||
|
||||
let textField = UITextField(frame: .zero)
|
||||
self.textField = textField
|
||||
textField.translatesAutoresizingMaskIntoConstraints = false
|
||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
textField.heightAnchor.constraint(equalToConstant: 24).isActive = true
|
||||
textField.font = MFStyler.fontForTextField()
|
||||
textField.smartQuotesType = .no
|
||||
textField.smartDashesType = .no
|
||||
textField.smartInsertDeleteType = .no
|
||||
MFStyler.styleTextField(textField)
|
||||
|
||||
container.addSubview(textField)
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 10),
|
||||
textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 16),
|
||||
container.bottomAnchor.constraint(equalTo: textField.bottomAnchor, constant: 10)])
|
||||
|
||||
|
||||
let dropDownCaretLabel = Label()
|
||||
self.dropDownCaretLabel = dropDownCaretLabel
|
||||
dropDownCaretLabel.setContentHuggingPriority(UILayoutPriority(900), for: .horizontal)
|
||||
@ -133,44 +93,12 @@ import UIKit
|
||||
dropDownCaretLabel.leadingAnchor.constraint(equalTo: textField.trailingAnchor, constant: 6).isActive = true
|
||||
container.trailingAnchor.constraint(equalTo: dropDownCaretLabel.trailingAnchor, constant: 16).isActive = true
|
||||
container.bottomAnchor.constraint(equalTo: dropDownCaretLabel.bottomAnchor).isActive = true
|
||||
dropDownCarrotWidth = dropDownCaretLabel.widthAnchor.constraint(equalToConstant: 0)
|
||||
dropDownCarrotWidth?.isActive = true
|
||||
dropDownCaretWidth = dropDownCaretLabel.widthAnchor.constraint(equalToConstant: 0)
|
||||
dropDownCaretWidth?.isActive = true
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
if let textField = textField {
|
||||
MFStyler.styleTextField(textField)
|
||||
}
|
||||
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
deinit {
|
||||
mfTextFieldDelegate = nil
|
||||
uiTextFieldDelegate = nil
|
||||
}
|
||||
|
||||
open override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
borderPath?.removeAllPoints()
|
||||
|
||||
if !hideBorder, let frame = fieldContainer?.frame {
|
||||
|
||||
borderPath = UIBezierPath()
|
||||
borderPath?.move(to: CGPoint(x: frame.origin.x, y: frame.origin.y + frame.size.height))
|
||||
borderPath?.addLine(to: CGPoint(x: frame.origin.x, y: frame.origin.y))
|
||||
borderPath?.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y))
|
||||
borderPath?.addLine(to: CGPoint(x: frame.origin.x + frame.size.width, y: frame.origin.y + frame.size.height))
|
||||
borderPath?.lineWidth = 1
|
||||
|
||||
let strokeColor = showError ? UIColor.mfPumpkin() : UIColor.mfSilver()
|
||||
strokeColor.setStroke()
|
||||
|
||||
borderPath?.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -237,15 +165,6 @@ import UIKit
|
||||
dropDownCaretLabel?.isHidden = false
|
||||
self.hasDropDown = true
|
||||
|
||||
case "password":
|
||||
textField?.isSecureTextEntry = true
|
||||
|
||||
case "number":
|
||||
textField?.keyboardType = .numberPad
|
||||
|
||||
case "email":
|
||||
textField?.keyboardType = .emailAddress
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@ -17,9 +17,7 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public weak var customDelegate: UITextFieldDelegate?
|
||||
|
||||
public var isNationalMdn = false
|
||||
public var isNationalMdn = true
|
||||
public var shouldValidateMDN = false
|
||||
|
||||
public var mdn: String? {
|
||||
@ -50,29 +48,17 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
//--------------------------------------------------
|
||||
|
||||
private func setup() {
|
||||
|
||||
textField?.delegate = self
|
||||
customDelegate = uiTextFieldDelegate
|
||||
isNationalMdn = true
|
||||
|
||||
textField?.keyboardType = .numberPad
|
||||
|
||||
let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar()
|
||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:)))
|
||||
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:)))
|
||||
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissTextFieldResponder(_:)))
|
||||
toolbar.items = [contacts, space, dismissButton]
|
||||
textField?.inputAccessoryView = toolbar
|
||||
}
|
||||
|
||||
// If you're using a MFViewController, you must set this to it.
|
||||
public override weak var uiTextFieldDelegate: UITextFieldDelegate? {
|
||||
get { return textField?.delegate }
|
||||
set {
|
||||
super.uiTextFieldDelegate = newValue
|
||||
customDelegate = uiTextFieldDelegate
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
@ -108,11 +94,6 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
return true
|
||||
}
|
||||
|
||||
@objc func dismissFieldInput(_ sender: Any?) {
|
||||
|
||||
textField?.resignFirstResponder()
|
||||
}
|
||||
|
||||
func getContacts(_ sender: Any?) {
|
||||
|
||||
let picker = CNContactPickerViewController()
|
||||
@ -161,7 +142,7 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
|
||||
textField.resignFirstResponder()
|
||||
|
||||
return customDelegate?.textFieldShouldReturn?(textField) ?? true
|
||||
return uiTextFieldDelegate?.textFieldShouldReturn?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
@ -170,18 +151,18 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
return false
|
||||
}
|
||||
|
||||
return customDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
|
||||
return uiTextFieldDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
|
||||
}
|
||||
|
||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
|
||||
textField.text = MVMCoreUIUtility.removeMdnFormat(textField.text)
|
||||
customDelegate?.textFieldDidBeginEditing?(textField)
|
||||
uiTextFieldDelegate?.textFieldDidBeginEditing?(textField)
|
||||
}
|
||||
|
||||
public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
customDelegate?.textFieldDidEndEditing?(textField)
|
||||
uiTextFieldDelegate?.textFieldDidEndEditing?(textField)
|
||||
|
||||
if validateAndColor() && isNationalMdn {
|
||||
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
|
||||
@ -194,16 +175,16 @@ class MdnEntryField: TextEntryField, ABPeoplePickerNavigationControllerDelegate,
|
||||
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
return uiTextFieldDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
return uiTextFieldDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
return uiTextFieldDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,233 +0,0 @@
|
||||
//
|
||||
// MdnTextField.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 10/14/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import AddressBookUI
|
||||
import ContactsUI
|
||||
import UIKit
|
||||
import MVMCore
|
||||
|
||||
|
||||
@objcMembers open class MdnTextField: TextField, UITextFieldDelegate, ABPeoplePickerNavigationControllerDelegate, CNContactPickerDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public weak var customDelegate: UITextFieldDelegate?
|
||||
public var isNationalMdn = false
|
||||
public var shouldValidateMDN = false
|
||||
|
||||
public var mdn: String? {
|
||||
get {
|
||||
guard let text = text else { return nil }
|
||||
|
||||
return MVMCoreUIUtility.removeMdnFormat(text)
|
||||
}
|
||||
set {
|
||||
guard let MDN = newValue else { return }
|
||||
text = MVMCoreUIUtility.formatMdn(MDN)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: .zero)
|
||||
setup()
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Setup
|
||||
//--------------------------------------------------
|
||||
|
||||
private func setup() {
|
||||
|
||||
textField?.delegate = self
|
||||
customDelegate = uiTextFieldDelegate
|
||||
isNationalMdn = true
|
||||
textField?.keyboardType = .numberPad
|
||||
|
||||
let toolbar = MVMCoreUICommonViewsUtility.makeEmptyToolbar()
|
||||
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
let contacts = UIBarButtonItem(title: MVMCoreUIUtility.hardcodedString(withKey: "textfield_contacts_barbutton"), style: .plain, target: self, action: #selector(getContacts(_:)))
|
||||
let dismissButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissFieldInput(_:)))
|
||||
toolbar.items = [contacts, space, dismissButton]
|
||||
textField?.inputAccessoryView = toolbar
|
||||
}
|
||||
|
||||
// If you're using a MFViewController, you must set this to it.
|
||||
public override weak var uiTextFieldDelegate: UITextFieldDelegate? {
|
||||
get {
|
||||
return textField?.delegate
|
||||
}
|
||||
set {
|
||||
super.uiTextFieldDelegate = newValue
|
||||
customDelegate = uiTextFieldDelegate
|
||||
|
||||
if newValue != nil {
|
||||
textField?.delegate = self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
func hasValidMdn() -> Bool {
|
||||
|
||||
guard let MDN = mdn else { return true }
|
||||
|
||||
if MDN.isEmpty {
|
||||
return true
|
||||
}
|
||||
|
||||
if isNationalMdn {
|
||||
return MVMCoreUIUtility.validateMDNString(MDN)
|
||||
}
|
||||
|
||||
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
|
||||
}
|
||||
|
||||
func validateAndColor() -> Bool {
|
||||
|
||||
if !shouldValidateMDN {
|
||||
let isValid = hasValidMdn()
|
||||
|
||||
if isValid {
|
||||
hideError()
|
||||
} else {
|
||||
self.errorMessage = getErrorMessage() ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
|
||||
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: textField)
|
||||
}
|
||||
|
||||
return isValid
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func getErrorMessage() -> String? {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@objc func dismissFieldInput(_ sender: Any?) {
|
||||
|
||||
if let delegate = uiTextFieldDelegate {
|
||||
delegate.perform(#selector(dismissFieldInput(_:)), with: textField)
|
||||
} else {
|
||||
textField?.resignFirstResponder()
|
||||
}
|
||||
}
|
||||
|
||||
func getContacts(_ sender: Any?) {
|
||||
|
||||
let picker = CNContactPickerViewController()
|
||||
picker.delegate = self
|
||||
picker.displayedPropertyKeys = ["phoneNumbers"]
|
||||
picker.predicateForEnablingContact = NSPredicate(format: "phoneNumbers.@count > 0")
|
||||
picker.predicateForSelectionOfProperty = NSPredicate(format: "key == 'phoneNumbers'")
|
||||
MVMCoreNavigationHandler.shared()?.present(picker, animated: true)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - ContactPicker Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
public func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
|
||||
|
||||
if contactProperty.value != nil && (contactProperty.value is CNPhoneNumber) {
|
||||
|
||||
let phoneNumber = contactProperty.value as? CNPhoneNumber
|
||||
let MDN = phoneNumber?.stringValue
|
||||
var unformattedMDN = MVMCoreUIUtility.removeMdnFormat(MDN)
|
||||
|
||||
// Sometimes user add extra 1 in front of mdn in their address book
|
||||
if isNationalMdn,
|
||||
let unformedMDN = unformattedMDN,
|
||||
unformedMDN.count == 11,
|
||||
unformedMDN[(unformedMDN.index(unformedMDN.startIndex, offsetBy: 0))] == "1" {
|
||||
|
||||
unformattedMDN = (unformedMDN as NSString).substring(from: 1)
|
||||
}
|
||||
|
||||
text = unformattedMDN
|
||||
|
||||
if let textField = textField {
|
||||
textFieldShouldReturn(textField)
|
||||
textFieldDidEndEditing(textField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - ImplementedTextField Delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
@discardableResult
|
||||
@objc public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
|
||||
textField.resignFirstResponder()
|
||||
|
||||
return customDelegate?.textFieldShouldReturn?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||
|
||||
if !MVMCoreUIUtility.validate(string, withRegularExpression: RegularExpressionDigitOnly) {
|
||||
return false
|
||||
}
|
||||
|
||||
return customDelegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) ?? true
|
||||
}
|
||||
|
||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
|
||||
textField.text = MVMCoreUIUtility.removeMdnFormat(textField.text)
|
||||
customDelegate?.textFieldDidBeginEditing?(textField)
|
||||
}
|
||||
|
||||
public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
customDelegate?.textFieldDidEndEditing?(textField)
|
||||
|
||||
if validateAndColor() && isNationalMdn {
|
||||
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Passed Along TextField delegate
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldBeginEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldEndEditing?(textField) ?? true
|
||||
}
|
||||
|
||||
@objc public func textFieldShouldClear(_ textField: UITextField) -> Bool {
|
||||
|
||||
return customDelegate?.textFieldShouldClear?(textField) ?? true
|
||||
}
|
||||
}
|
||||
@ -200,6 +200,11 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
@objc func dismissTextFieldResponder(_ sender: Any?) {
|
||||
|
||||
textField?.resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing for change
|
||||
//--------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user