Further development of Entry Field.

This commit is contained in:
Kevin G Christiano 2019-12-13 12:54:43 -05:00
parent 59008f87d0
commit 44ff5e9d3c
7 changed files with 86 additions and 69 deletions

View File

@ -22,7 +22,6 @@ import UIKit
return calendar
}()
// TODO: Pull this out into Styler or some class akin to it.
public var formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
@ -38,7 +37,6 @@ import UIKit
@objc public override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
@objc public convenience init() {
@ -58,7 +56,8 @@ import UIKit
// MARK: - Methods
//--------------------------------------------------
@objc private func setup() {
public override func setupFieldContainerContent(_ container: UIView) {
super.setupFieldContainerContent(container)
datePicker = MVMCoreUICommonViewsUtility.addDatePicker(to: textField)
datePicker?.addTarget(self, action: #selector(pickerValueChanged), for: .valueChanged)
@ -81,7 +80,7 @@ import UIKit
let pickedDate = datePicker?.date
setTextWith(date: pickedDate)
textField.resignFirstResponder()
resignFirstResponder()
return pickedDate
}

View File

@ -34,6 +34,9 @@ import UIKit
private var previousSize: CGFloat = 0.0
// Default dimensions of the DigitBox
static let size: CGSize = CGSize(width: 39, height: 44)
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------
@ -97,7 +100,7 @@ import UIKit
guard constraints.isEmpty else { return }
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .white
backgroundColor = .clear
addSubview(digitField)
digitField.delegate = self
@ -112,9 +115,9 @@ import UIKit
digitField.centerYAnchor.constraint(equalTo: centerYAnchor),
digitField.centerXAnchor.constraint(equalTo: centerXAnchor)])
widthConstraint = widthAnchor.constraint(equalToConstant: 39)
widthConstraint = widthAnchor.constraint(equalToConstant: DigitBox.size.width)
widthConstraint?.isActive = true
heightConstraint = heightAnchor.constraint(equalToConstant: 44)
heightConstraint = heightAnchor.constraint(equalToConstant: DigitBox.size.height)
heightConstraint?.isActive = true
if let bottomBar = bottomBar {

View File

@ -105,7 +105,7 @@ import UIKit
}
}
}
/// Sets the text of titleLabel
public var title: String? {
get { return titleLabel.text }
@ -177,10 +177,10 @@ import UIKit
/// Initial configuration of class and view.
@objc final public override func setupView() {
super.setupView()
guard subviews.isEmpty else { return }
translatesAutoresizingMaskIntoConstraints = false
isAccessibilityElement = false
setContentCompressionResistancePriority(.required, for: .vertical)
accessibilityElements = [titleLabel, feedbackLabel]

View File

@ -97,23 +97,22 @@ import MVMCore
return MVMCoreUIUtility.validateInternationalMDNString(MDN)
}
@objc public func validate() -> Bool {
@objc public override func validateTextField() -> Bool {
if !shouldValidateMDN {
let isValid = hasValidMDN()
guard !shouldValidateMDN else { return true }
let isValid = hasValidMDN()
if isValid {
showError = false
if isValid {
showError = false
} else {
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
showError = true
UIAccessibility.post(notification: .layoutChanged, argument: textField)
}
return isValid
} else {
errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message")
showError = true
UIAccessibility.post(notification: .layoutChanged, argument: textField)
}
return true
return isValid
}
@objc public func getContacts(_ sender: Any?) {
@ -183,7 +182,7 @@ import MVMCore
proprietorTextDelegate?.textFieldDidEndEditing?(textField)
if validate() && isNationalMDN {
if validateTextField() && isNationalMDN {
textField.text = MVMCoreUIUtility.formatMdn(textField.text)
}
}

View File

@ -42,7 +42,13 @@ import UIKit
/// 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: Bool = false
private var observingForChange: Bool = false
/// Validate on each entry in the textField. Default: false
public var validateEachCharacter: Bool = false
/// Validate when user resigns editing. Default: true
public var validateWhenDoneEditing: Bool = true
//--------------------------------------------------
// MARK: - Computed Properties
@ -75,7 +81,6 @@ import UIKit
get { return textField.text }
set {
textField.text = newValue
valueChanged()
}
}
@ -101,7 +106,7 @@ import UIKit
// MARK: - Delegate Properties
//--------------------------------------------------
/// The delegate and block for validation. Validates if the text that the user has entered is valid or not. Checked after each change if there is a delegate.
/// The delegate and block for validation. Validates if the text that the user has entered.
public weak var observingTextFieldDelegate: ObservingTextFieldDelegate? {
didSet {
if observingTextFieldDelegate != nil && !observingForChange {
@ -193,33 +198,30 @@ import UIKit
// MARK: - Observing for Change (TextFieldDelegate)
//--------------------------------------------------
public func defaultValidationBlock() {
validationBlock = { enteredValue in
guard let enteredValue = enteredValue else { return false }
return enteredValue.count > 0
}
}
@discardableResult
@objc override open func resignFirstResponder() -> Bool {
if validateWhenDoneEditing {
validateTextField()
}
textField.resignFirstResponder()
isSelected = false
return true
}
@objc func dismissFieldInput(_ sender: Any?) {
_ = resignFirstResponder()
}
public func defaultValidationBlock() {
validationBlock = { enteredValue in
return (enteredValue?.count ?? 0) > 0
}
}
/// Executes on UITextField.textDidChangeNotification
@objc func valueChanged() {
if !showError {
feedback = ""
}
/// Validates the text of the entry field.
@discardableResult
@objc public func validateTextField() -> Bool {
// If validation not set, input will always be valid
isValid = validationBlock?(text) ?? true
if !isValid {
@ -227,22 +229,10 @@ import UIKit
observingTextFieldDelegate?.isInvalid?(textfield: self)
} else if isValid {
if showError == true {
showError = false
}
isSelected = true
observingTextFieldDelegate?.isValid?(textfield: self)
}
}
/// Executes on UITextField.textDidEndEditingNotification
@objc func endInputing() {
if isValid {
showError = false
entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
}
return isValid
}
/// Executes on UITextField.textDidBeginEditingNotification
@ -251,9 +241,33 @@ import UIKit
isSelected = true
textField.becomeFirstResponder()
}
/// Executes on UITextField.textDidChangeNotification (every character entry)
@objc func valueChanged() {
guard validateEachCharacter else { return }
validateTextField()
}
/// Executes on UITextField.textDidEndEditingNotification
@objc func endInputing() {
if isValid {
showError = false
entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor
}
resignFirstResponder()
}
@objc func dismissFieldInput(_ sender: Any?) {
resignFirstResponder()
}
}
// MARK: - Molecular
// MARK: - MVMCoreUIMoleculeViewProtocol
extension TextEntryField {
@objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {

View File

@ -44,7 +44,7 @@ import UIKit
}
}
/// MARK:- MVMCoreViewProtocol
// MARK:- MVMCoreViewProtocol
extension View: MVMCoreViewProtocol {
open func updateView(_ size: CGFloat) {}
@ -56,7 +56,7 @@ extension View: MVMCoreViewProtocol {
}
}
/// MARK:- MVMCoreUIMoleculeViewProtocol
// MARK:- MVMCoreUIMoleculeViewProtocol
extension View: MVMCoreUIMoleculeViewProtocol {
open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {

View File

@ -33,8 +33,9 @@ import UIKit
private(set) var fieldState: FieldState = .original {
didSet (oldState) {
// Will not update if new state is the same as old.
guard fieldState != oldState else { return }
fieldState.setStateUI(for: self)
if fieldState != oldState {
fieldState.setStateUI(for: self)
}
}
}
@ -100,8 +101,8 @@ import UIKit
_isLocked = false
_isEnabled = true
if selected && showError {
fieldState = .selectedError
if _showError {
fieldState = selected ? .selectedError : .error
} else {
fieldState = selected ? .selected : .original
}
@ -174,6 +175,7 @@ import UIKit
_showError = false
subviews.forEach { $0.removeFromSuperview() }
borderPath.removeAllPoints()
}
//--------------------------------------------------
@ -277,10 +279,10 @@ import UIKit
layoutIfNeeded()
}
}
//--------------------------------------------------
// MARK: - Molecular
//--------------------------------------------------
}
// MARK:- MVMCoreUIMoleculeViewProtocol
extension EntryFieldContainer {
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)