Latest changes to make it better.
This commit is contained in:
parent
d8030b178f
commit
37ddf23278
@ -24,6 +24,7 @@ import UIKit
|
||||
textField.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
textField.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
textField.textAlignment = .center
|
||||
textField.font = MFStyler.fontForTextField()
|
||||
textField.keyboardType = .numberPad
|
||||
return textField
|
||||
}()
|
||||
@ -72,6 +73,7 @@ import UIKit
|
||||
|
||||
private weak var widthConstraint: NSLayoutConstraint?
|
||||
private weak var heightConstraint: NSLayoutConstraint?
|
||||
private weak var digitFieldHeight: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
@ -106,12 +108,14 @@ import UIKit
|
||||
digitField.delegate = self
|
||||
digitField.didDeleteDelegate = self
|
||||
|
||||
digitFieldHeight = digitField.heightAnchor.constraint(equalToConstant: 24)
|
||||
digitFieldHeight?.isActive = true
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
digitField.heightAnchor.constraint(equalToConstant: 24),
|
||||
digitField.topAnchor.constraint(greaterThanOrEqualTo: topAnchor),
|
||||
digitField.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
|
||||
bottomAnchor.constraint(greaterThanOrEqualTo: digitField.bottomAnchor),
|
||||
trailingAnchor.constraint(greaterThanOrEqualTo: digitField.trailingAnchor),
|
||||
digitField.topAnchor.constraint(equalTo: topAnchor, constant: PaddingOne),
|
||||
digitField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: PaddingOne),
|
||||
bottomAnchor.constraint(equalTo: digitField.bottomAnchor, constant: PaddingOne),
|
||||
trailingAnchor.constraint(equalTo: digitField.trailingAnchor, constant: PaddingOne),
|
||||
digitField.centerYAnchor.constraint(equalTo: centerYAnchor),
|
||||
digitField.centerXAnchor.constraint(equalTo: centerXAnchor)])
|
||||
|
||||
@ -145,7 +149,8 @@ import UIKit
|
||||
@objc open override func reset() {
|
||||
super.reset()
|
||||
|
||||
digitField.text = nil
|
||||
backgroundColor = .clear
|
||||
digitField.font = MFStyler.fontForTextField()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -161,28 +166,31 @@ import UIKit
|
||||
super.updateView(size)
|
||||
|
||||
if !MVMCoreGetterUtility.fequal(a: Float(size), b: Float(previousSize)) {
|
||||
MFStyler.styleTextField(digitField)
|
||||
digitField.font = MFFonts.mfFont55Rg(28)
|
||||
|
||||
|
||||
var width: CGFloat = 0
|
||||
var height: CGFloat = 0
|
||||
var pointSize: CGFloat = 13
|
||||
|
||||
let sizeObject = MFSizeObject(standardBlock: {
|
||||
width = 39
|
||||
height = 44
|
||||
pointSize = 16
|
||||
|
||||
}, smalliPhone: {
|
||||
width = 35
|
||||
height = 38
|
||||
pointSize = 13
|
||||
|
||||
}, standardiPadPortraitBlock: {
|
||||
width = 59
|
||||
height = 74
|
||||
pointSize = 32
|
||||
})
|
||||
|
||||
sizeObject?.performBlockBase(onSize: size)
|
||||
widthConstraint?.constant = width
|
||||
heightConstraint?.constant = height
|
||||
digitField.font = MFFonts.mfFont55Rg(pointSize)
|
||||
previousSize = size
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,53 @@ import UIKit
|
||||
// MARK: - Stored Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
private(set) var numberOfDigits = 4
|
||||
private(set) var numberOfDigits = 4 {
|
||||
didSet {
|
||||
guard entryFieldContainer.subviews.isEmpty || oldValue != numberOfDigits else { return }
|
||||
|
||||
var accessibleElements: [Any] = [titleLabel]
|
||||
|
||||
if numberOfDigits > 0 {
|
||||
var digitBoxes = [DigitBox]()
|
||||
|
||||
for _ in 0..<numberOfDigits {
|
||||
digitBoxes.append(createDigitField())
|
||||
}
|
||||
|
||||
self.digitBoxes = digitBoxes
|
||||
guard let space = MFSizeObject(standardSize: 5, smalliPhoneSize: 3)?.getValueBasedOnScreenSize() else { return }
|
||||
|
||||
var prevBox: DigitBox?
|
||||
|
||||
for (index, box) in digitBoxes.enumerated() {
|
||||
accessibleElements.append(box)
|
||||
entryFieldContainer.addSubview(box)
|
||||
|
||||
box.topAnchor.constraint(equalTo: entryFieldContainer.topAnchor).isActive = true
|
||||
entryFieldContainer.bottomAnchor.constraint(equalTo: box.bottomAnchor).isActive = true
|
||||
|
||||
if index == 0 {
|
||||
box.leadingAnchor.constraint(equalTo: entryFieldContainer.leadingAnchor).isActive = true
|
||||
|
||||
} else if index == digitBoxes.count - 1 {
|
||||
if let prevTrailingAnchor = prevBox?.trailingAnchor {
|
||||
box.leadingAnchor.constraint(equalTo: prevTrailingAnchor, constant: space).isActive = true
|
||||
}
|
||||
entryFieldContainer.trailingAnchor.constraint(greaterThanOrEqualTo: box.trailingAnchor).isActive = true
|
||||
|
||||
} else {
|
||||
if let prevTrailingAnchor = prevBox?.trailingAnchor {
|
||||
box.leadingAnchor.constraint(equalTo: prevTrailingAnchor, constant: space).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
prevBox = box
|
||||
}
|
||||
}
|
||||
|
||||
accessibilityElements = accessibleElements + [feedbackLabel]
|
||||
}
|
||||
}
|
||||
|
||||
/// Monitors if fields are being selected internally.
|
||||
private var switchFieldsAutomatically = false
|
||||
@ -130,7 +176,6 @@ import UIKit
|
||||
@objc public convenience init(numberOfDigits: Int, secureDigits: Bool = false) {
|
||||
self.init(frame: .zero)
|
||||
self.numberOfDigits = numberOfDigits
|
||||
assembleDigitFieldsView(size: MVMCoreUISplitViewController.getDetailViewWidth())
|
||||
|
||||
if secureDigits {
|
||||
setAsSecureTextEntry(true)
|
||||
@ -162,49 +207,6 @@ import UIKit
|
||||
return digitBox
|
||||
}
|
||||
|
||||
@objc func assembleDigitFieldsView(size: CGFloat) {
|
||||
|
||||
var accessibleElements: [Any] = [titleLabel]
|
||||
|
||||
resetDigitBoxes()
|
||||
|
||||
if numberOfDigits > 0 {
|
||||
var digitBoxes = [DigitBox]()
|
||||
|
||||
for _ in 0..<numberOfDigits {
|
||||
digitBoxes.append(createDigitField())
|
||||
}
|
||||
|
||||
self.digitBoxes = digitBoxes
|
||||
guard let space = MFSizeObject(standardSize: 5, smalliPhoneSize: 3)?.getValueBasedOnScreenSize() else { return }
|
||||
|
||||
var prevBox: DigitBox?
|
||||
|
||||
for (index, box) in digitBoxes.enumerated() {
|
||||
accessibleElements.append(box)
|
||||
entryFieldContainer.addSubview(box)
|
||||
|
||||
box.topAnchor.constraint(equalTo: entryFieldContainer.topAnchor).isActive = true
|
||||
entryFieldContainer.bottomAnchor.constraint(equalTo: box.bottomAnchor).isActive = true
|
||||
|
||||
if index == 0 {
|
||||
box.leadingAnchor.constraint(equalTo: entryFieldContainer.leadingAnchor).isActive = true
|
||||
|
||||
} else if index == digitBoxes.count - 1 {
|
||||
box.leadingAnchor.constraint(equalTo: prevBox!.trailingAnchor, constant: space).isActive = true
|
||||
entryFieldContainer.trailingAnchor.constraint(greaterThanOrEqualTo: box.trailingAnchor).isActive = true
|
||||
|
||||
} else {
|
||||
box.leadingAnchor.constraint(equalTo: prevBox!.trailingAnchor, constant: space).isActive = true
|
||||
}
|
||||
|
||||
prevBox = box
|
||||
}
|
||||
}
|
||||
|
||||
accessibilityElements = accessibleElements + [feedbackLabel]
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
@ -218,40 +220,23 @@ import UIKit
|
||||
guard let self = self else { return }
|
||||
|
||||
if !self.digitBoxes.isEmpty {
|
||||
|
||||
self.digitBoxes.forEach { $0.updateView(size) }
|
||||
self.layoutIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc open override func reset() {
|
||||
super.reset()
|
||||
|
||||
resetDigitBoxes()
|
||||
}
|
||||
|
||||
func resetDigitBoxes() {
|
||||
|
||||
digitBoxes.forEach { $0.reset() }
|
||||
digitBoxes = []
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc public func setAsSecureTextEntry(_ secureEntry: Bool) {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
for (index, field) in self.digitBoxes.enumerated() {
|
||||
field.digitField.isSecureTextEntry = secureEntry
|
||||
|
||||
for (index, field) in self.digitBoxes.enumerated() {
|
||||
field.digitField.isSecureTextEntry = secureEntry
|
||||
|
||||
// Accessibility - 33704 fix voice over will read what pin user is filling
|
||||
field.accessibilityLabel = String(format: "PIN %lu of %lu", UInt(index) + 1, UInt(self.digitBoxes.count))
|
||||
}
|
||||
// Accessibility - 33704 fix voice over will read what pin user is filling
|
||||
field.accessibilityLabel = String(format: "PIN %lu of %lu", UInt(index) + 1, UInt(self.digitBoxes.count))
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +248,7 @@ import UIKit
|
||||
return enteredValue.count > 0 && enteredValue.count == self.digitBoxes.count
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc public func selectPreviousDigitField(_ currentTextField: UITextField?, clear: Bool) {
|
||||
|
||||
var selectPreviousField = false
|
||||
@ -310,6 +295,10 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Observing TextField Changes
|
||||
//--------------------------------------------------
|
||||
|
||||
@objc override func startEditing() {
|
||||
|
||||
selectedDigitBox?.isSelected = true
|
||||
@ -442,12 +431,7 @@ extension DigitEntryField {
|
||||
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
let digits = dictionary["digits"] as? Int ?? 4
|
||||
if digits != numberOfDigits {
|
||||
numberOfDigits = digits
|
||||
}
|
||||
|
||||
assembleDigitFieldsView(size: MVMCoreUIUtility.getWidth())
|
||||
numberOfDigits = dictionary["digits"] as? Int ?? 4
|
||||
|
||||
if let _ = dictionary["secureEntry"] as? Bool {
|
||||
setAsSecureTextEntry(true)
|
||||
|
||||
@ -28,6 +28,7 @@ import UIKit
|
||||
|
||||
public private(set) var entryFieldContainer = EntryFieldContainer()
|
||||
|
||||
/// Provides contextual information on the TextField.
|
||||
public private(set) var feedbackLabel: Label = {
|
||||
let label = Label()
|
||||
label.font = MFStyler.fontForTextFieldUnderLabel()
|
||||
@ -50,7 +51,13 @@ import UIKit
|
||||
public var fieldKey: String?
|
||||
|
||||
public var errorMessage: String?
|
||||
public var standardMessage: String?
|
||||
public var standardMessage: String? {
|
||||
didSet {
|
||||
if !showError {
|
||||
feedback = standardMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
@ -60,12 +67,8 @@ import UIKit
|
||||
public var isEnabled: Bool {
|
||||
get { return entryFieldContainer.isEnabled }
|
||||
set (enabled) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryFieldContainer.isEnabled = enabled
|
||||
self.feedbackLabel.textColor = enabled ? .black : .mfSilver()
|
||||
}
|
||||
self.feedbackLabel.textColor = enabled ? .black : .mfSilver()
|
||||
self.entryFieldContainer.isEnabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,12 +76,8 @@ import UIKit
|
||||
public var showError: Bool {
|
||||
get { return entryFieldContainer.showError }
|
||||
set (error) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryFieldContainer.showError = error
|
||||
self.feedback = error ? self.errorMessage : self.standardMessage
|
||||
}
|
||||
self.feedback = error ? self.errorMessage : self.standardMessage
|
||||
self.entryFieldContainer.showError = error
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,11 +85,7 @@ import UIKit
|
||||
public var isLocked: Bool {
|
||||
get { return entryFieldContainer.isLocked }
|
||||
set (locked) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryFieldContainer.isLocked = locked
|
||||
}
|
||||
self.entryFieldContainer.isLocked = locked
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,11 +93,7 @@ import UIKit
|
||||
public var isSelected: Bool {
|
||||
get { return entryFieldContainer.isSelected }
|
||||
set (selected) {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryFieldContainer.isSelected = selected
|
||||
}
|
||||
self.entryFieldContainer.isSelected = selected
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +117,12 @@ import UIKit
|
||||
get { return feedbackLabel.text }
|
||||
set (newFeedback) {
|
||||
feedbackLabel.text = newFeedback
|
||||
entryFieldContainer.refreshUI()
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.entryFieldContainer.refreshUI()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +190,7 @@ import UIKit
|
||||
titleLabelLeading?.isActive = true
|
||||
|
||||
addSubview(entryFieldContainer)
|
||||
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
setupFieldContainerContent(entryFieldContainer)
|
||||
|
||||
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 4)
|
||||
@ -238,15 +235,13 @@ import UIKit
|
||||
super.reset()
|
||||
|
||||
backgroundColor = .clear
|
||||
titleLabel.reset()
|
||||
feedbackLabel.reset()
|
||||
isAccessibilityElement = false
|
||||
titleLabel.font = MFStyler.fontB3()
|
||||
titleLabel.textColor = .mfBattleshipGrey()
|
||||
feedbackLabel.font = MFStyler.fontForTextFieldUnderLabel()
|
||||
feedbackLabel.textColor = .black
|
||||
entryFieldContainer.reset()
|
||||
}
|
||||
|
||||
open func feedbackStandardMessage(_ message: String? = nil) {
|
||||
|
||||
feedback = message ?? standardMessage
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
@ -268,13 +263,12 @@ extension EntryField {
|
||||
isEnabled = false
|
||||
}
|
||||
|
||||
if let errMessage = dictionary[KeyErrorMessage] as? String {
|
||||
errorMessage = errMessage
|
||||
}
|
||||
|
||||
if let feedback = dictionary["feedback"] as? String {
|
||||
self.standardMessage = feedback
|
||||
feedbackStandardMessage()
|
||||
}
|
||||
|
||||
if let errMessage = dictionary[KeyErrorMessage] as? String {
|
||||
errorMessage = errMessage
|
||||
}
|
||||
|
||||
if let isLocked = dictionary["isLocked"] as? Bool {
|
||||
|
||||
@ -52,7 +52,7 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
|
||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||
super.setupFieldContainerContent(container)
|
||||
|
||||
|
||||
@ -184,6 +184,12 @@ import UIKit
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
textField.font = MFStyler.fontForTextField()
|
||||
}
|
||||
|
||||
@objc deinit {
|
||||
setBothTextDelegates(to: nil)
|
||||
}
|
||||
|
||||
@ -34,7 +34,11 @@ import UIKit
|
||||
didSet (oldState) {
|
||||
// Will not update if new state is the same as old.
|
||||
if fieldState != oldState {
|
||||
fieldState.setStateUI(for: self)
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.fieldState.setStateUI(for: self)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,18 +170,6 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
isEnabled = true
|
||||
_isLocked = false
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
subviews.forEach { $0.removeFromSuperview() }
|
||||
borderPath.removeAllPoints()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw States
|
||||
//--------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user