diff --git a/VDS/Components/DatePicker/DatePicker.swift b/VDS/Components/DatePicker/DatePicker.swift
index a61b70a5..fdc6e05f 100644
--- a/VDS/Components/DatePicker/DatePicker.swift
+++ b/VDS/Components/DatePicker/DatePicker.swift
@@ -101,15 +101,11 @@ open class DatePicker: EntryFieldBase, DatePickerViewControllerDelegate, UIPopov
open override func setup() {
super.setup()
- fieldStackView.isAccessibilityElement = true
- fieldStackView.accessibilityLabel = "Date Picker"
- fieldStackView.accessibilityHint = "Double Tap to open"
-
// setting color config
selectedDateLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable()
// tap gesture
- fieldStackView
+ containerView
.publisher(for: UITapGestureRecognizer())
.sink { [weak self] _ in
guard let self else { return }
@@ -144,14 +140,7 @@ open class DatePicker: EntryFieldBase, DatePickerViewControllerDelegate, UIPopov
selectedDateLabel.isEnabled = isEnabled
calendarIcon.color = iconColorConfiguration.getColor(self)
}
-
- open override func updateAccessibility() {
- super.updateAccessibility()
- fieldStackView.accessibilityLabel = "Date Picker, \(accessibilityLabelText)"
- fieldStackView.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open."
- fieldStackView.accessibilityValue = value
- }
-
+
/// Resets to default settings.
open override func reset() {
super.reset()
@@ -184,7 +173,7 @@ open class DatePicker: EntryFieldBase, DatePickerViewControllerDelegate, UIPopov
controller.dismiss(animated: true) { [weak self] in
guard let self else { return }
self.sendActions(for: .valueChanged)
- UIAccessibility.post(notification: .layoutChanged, argument: self.fieldStackView)
+ UIAccessibility.post(notification: .layoutChanged, argument: self.containerView)
}
}
diff --git a/VDS/Components/DropdownSelect/DropdownSelect.swift b/VDS/Components/DropdownSelect/DropdownSelect.swift
index b06eac6a..1496f392 100644
--- a/VDS/Components/DropdownSelect/DropdownSelect.swift
+++ b/VDS/Components/DropdownSelect/DropdownSelect.swift
@@ -66,6 +66,8 @@ open class DropdownSelect: EntryFieldBase {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
+ internal override var responder: UIResponder? { dropdownField }
+
internal var minWidthDefault = 66.0
internal var minWidthInlineLabel = 102.0
internal override var minWidth: CGFloat { showInlineLabel ? minWidthInlineLabel : minWidthDefault }
@@ -131,7 +133,6 @@ open class DropdownSelect: EntryFieldBase {
open override func setup() {
super.setup()
- fieldStackView.isAccessibilityElement = true
inlineDisplayLabel.isAccessibilityElement = true
dropdownField.width(0)
@@ -276,57 +277,11 @@ open class DropdownSelect: EntryFieldBase {
statusIcon.color = iconColorConfiguration.getColor(self)
}
- open override func updateAccessibility() {
- super.updateAccessibility()
- fieldStackView.accessibilityLabel = "Dropdown Select, \(accessibilityLabelText)"
- fieldStackView.accessibilityHint = isReadOnly || !isEnabled ? "" : "has popup, Double tap to open."
- fieldStackView.accessibilityValue = value
- }
-
- open override var accessibilityElements: [Any]? {
- get {
- var elements = [Any]()
- elements.append(contentsOf: [titleLabel, fieldStackView])
-
- if showError {
- elements.append(statusIcon)
- if let errorText, !errorText.isEmpty {
- elements.append(errorLabel)
- }
- }
-
- if let helperText, !helperText.isEmpty {
- elements.append(helperLabel)
- }
-
- return elements
- }
-
- set { super.accessibilityElements = newValue }
- }
-
-
@objc open func pickerDoneClicked() {
optionsPicker.isHidden = true
dropdownField.resignFirstResponder()
setNeedsUpdate()
- UIAccessibility.post(notification: .layoutChanged, argument: fieldStackView)
- }
-
- open override var canBecomeFirstResponder: Bool {
- return dropdownField.canBecomeFirstResponder
- }
-
- open override func becomeFirstResponder() -> Bool {
- return dropdownField.becomeFirstResponder()
- }
-
- open override var canResignFirstResponder: Bool {
- return dropdownField.canResignFirstResponder
- }
-
- open override func resignFirstResponder() -> Bool {
- return dropdownField.resignFirstResponder()
+ UIAccessibility.post(notification: .layoutChanged, argument: containerView)
}
}
@@ -337,8 +292,8 @@ extension DropdownSelect: UIPickerViewDelegate, UIPickerViewDataSource {
internal func launchPicker() {
if optionsPicker.isHidden {
- UIAccessibility.post(notification: .layoutChanged, argument: optionsPicker)
dropdownField.becomeFirstResponder()
+ UIAccessibility.post(notification: .layoutChanged, argument: optionsPicker)
} else {
dropdownField.resignFirstResponder()
}
diff --git a/VDS/Components/TextFields/EntryFieldBase.swift b/VDS/Components/TextFields/EntryFieldBase.swift
index 2111a7f0..4e7422ee 100644
--- a/VDS/Components/TextFields/EntryFieldBase.swift
+++ b/VDS/Components/TextFields/EntryFieldBase.swift
@@ -40,6 +40,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
+ internal var responder: UIResponder? { return nil }
+
internal let mainStackView = UIStackView().with {
$0.axis = .vertical
$0.alignment = .fill
@@ -95,6 +97,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
internal var containerView: UIView = {
return UIView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
+ $0.isAccessibilityElement = true
}
}()
@@ -243,7 +246,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
open var accessibilityLabelText: String {
var accessibilityLabels = [String]()
- if let text = titleLabel.text {
+
+ if let text = titleLabel.text?.trimmingCharacters(in: .whitespaces) {
accessibilityLabels.append(text)
}
if isReadOnly {
@@ -255,9 +259,14 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
if let errorText, showError {
accessibilityLabels.append("error, \(errorText)")
}
+
+ accessibilityLabels.append("\(Self.self)")
+
return accessibilityLabels.joined(separator: ", ")
}
+ open var accessibilityHintText: String = "Double tap to open"
+
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
@@ -360,6 +369,22 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
isReadOnly = false
onChange = nil
}
+
+ open override var canBecomeFirstResponder: Bool {
+ responder?.canBecomeFirstResponder ?? super.canBecomeFirstResponder
+ }
+
+ open override func becomeFirstResponder() -> Bool {
+ responder?.becomeFirstResponder() ?? super.becomeFirstResponder()
+ }
+
+ open override var canResignFirstResponder: Bool {
+ responder?.canResignFirstResponder ?? super.canResignFirstResponder
+ }
+
+ open override func resignFirstResponder() -> Bool {
+ responder?.resignFirstResponder() ?? super.resignFirstResponder()
+ }
//--------------------------------------------------
// MARK: - Public Methods
@@ -447,6 +472,35 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable {
}
}
+ open override func updateAccessibility() {
+ super.updateAccessibility()
+ containerView.accessibilityLabel = accessibilityLabelText
+ containerView.accessibilityHint = isReadOnly || !isEnabled ? "" : accessibilityHintText
+ containerView.accessibilityValue = value
+ }
+
+ open override var accessibilityElements: [Any]? {
+ get {
+ var elements = [Any]()
+ elements.append(contentsOf: [titleLabel, containerView])
+
+ if showError {
+ elements.append(statusIcon)
+ if let errorText, !errorText.isEmpty {
+ elements.append(errorLabel)
+ }
+ }
+
+ if let helperText, !helperText.isEmpty {
+ elements.append(helperLabel)
+ }
+
+ return elements
+ }
+
+ set { super.accessibilityElements = newValue }
+ }
+
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift
index 3764c0c3..c2f779d4 100644
--- a/VDS/Components/TextFields/InputField/InputField.swift
+++ b/VDS/Components/TextFields/InputField/InputField.swift
@@ -34,6 +34,8 @@ open class InputField: EntryFieldBase {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
+ internal override var responder: UIResponder? { textField }
+
internal override var containerBackgroundColor: UIColor {
if showSuccess {
return backgroundColorConfiguration.getColor(self)
@@ -102,6 +104,7 @@ open class InputField: EntryFieldBase {
open var textField = TextField().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.textStyle = TextStyle.bodyLarge
+ $0.isAccessibilityElement = false
}
/// Color configuration for the textField.
@@ -181,6 +184,8 @@ open class InputField: EntryFieldBase {
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
+ accessibilityHintText = "Double tap to edit"
+
textField.heightAnchor.constraint(equalToConstant: 20).isActive = true
textField.delegate = self
bottomContainerStackView.insertArrangedSubview(successLabel, at: 0)
@@ -227,13 +232,7 @@ open class InputField: EntryFieldBase {
textField.isEnabled = isEnabled
textField.isUserInteractionEnabled = isEnabled && !isReadOnly
}
-
- open override func updateAccessibility() {
- super.updateAccessibility()
- textField.accessibilityLabel = accessibilityLabelText
- textField.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open."
- }
-
+
open override func updateErrorLabel() {
super.updateErrorLabel()
@@ -264,7 +263,7 @@ open class InputField: EntryFieldBase {
open override var accessibilityElements: [Any]? {
get {
var elements = [Any]()
- elements.append(contentsOf: [titleLabel, textField])
+ elements.append(contentsOf: [titleLabel, containerView])
if showError {
elements.append(statusIcon)
if let errorText, !errorText.isEmpty {
@@ -283,22 +282,6 @@ open class InputField: EntryFieldBase {
set { super.accessibilityElements = newValue }
}
-
- open override var canBecomeFirstResponder: Bool {
- return textField.canBecomeFirstResponder
- }
-
- open override func becomeFirstResponder() -> Bool {
- return textField.becomeFirstResponder()
- }
-
- open override var canResignFirstResponder: Bool {
- return textField.canResignFirstResponder
- }
-
- open override func resignFirstResponder() -> Bool {
- return textField.resignFirstResponder()
- }
}
extension InputField: UITextFieldDelegate {
@@ -311,6 +294,7 @@ extension InputField: UITextFieldDelegate {
public func textFieldDidEndEditing(_ textField: UITextField) {
fieldType.handler().textFieldDidEndEditing(self, textField: textField)
validate()
+ UIAccessibility.post(notification: .layoutChanged, argument: self.containerView)
}
public func textFieldDidChangeSelection(_ textField: UITextField) {
diff --git a/VDS/Components/TextFields/TextArea/TextArea.swift b/VDS/Components/TextFields/TextArea/TextArea.swift
index b1c244e5..a487dc53 100644
--- a/VDS/Components/TextFields/TextArea/TextArea.swift
+++ b/VDS/Components/TextFields/TextArea/TextArea.swift
@@ -32,6 +32,8 @@ open class TextArea: EntryFieldBase {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
+ internal override var responder: UIResponder? { textView }
+
internal var textViewHeightConstraint: NSLayoutConstraint?
internal var inputFieldStackView: UIStackView = {
@@ -42,14 +44,14 @@ open class TextArea: EntryFieldBase {
$0.spacing = VDSLayout.space3X
}
}()
-
+
open var characterCounterLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical)
$0.textStyle = .bodySmall
$0.textAlignment = .right
$0.numberOfLines = 1
}
-
+
open var minHeight: Height = .twoX { didSet { setNeedsUpdate() } }
//--------------------------------------------------
@@ -101,13 +103,15 @@ open class TextArea: EntryFieldBase {
open override var value: String? {
return textView.text
}
-
+
/// UITextView shown in the TextArea.
open var textView = TextView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.sizeToFit()
- $0.isScrollEnabled = false
+ $0.isAccessibilityElement = false
+ $0.isScrollEnabled = true
$0.textContainerInset = .zero
+ $0.autocorrectionType = .no
$0.textContainer.lineFragmentPadding = 0
}
@@ -137,10 +141,8 @@ open class TextArea: EntryFieldBase {
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
- fieldStackView.pinToSuperView(.uniform(VDSFormControls.spaceInset))
-
- textView.isScrollEnabled = true
- textView.autocorrectionType = .no
+
+ accessibilityHintText = "Double tap to edit"
//events
textView
@@ -159,6 +161,7 @@ open class TextArea: EntryFieldBase {
.publisher(for: .editingDidEnd)
.sink { [weak self] _ in
self?.validate()
+ UIAccessibility.post(notification: .layoutChanged, argument: self?.containerView)
}.store(in: &subscribers)
textViewHeightConstraint = textView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height)
@@ -192,13 +195,7 @@ open class TextArea: EntryFieldBase {
characterCounterLabel.surface = surface
highlightCharacterOverflow()
}
-
- open override func updateAccessibility() {
- super.updateAccessibility()
- textView.accessibilityLabel = accessibilityLabelText
- textView.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open."
- }
-
+
override func updateRules() {
super.updateRules()
@@ -222,46 +219,7 @@ open class TextArea: EntryFieldBase {
stackView.addArrangedSubview(characterCounterLabel)
return stackView
}
-
- open override var accessibilityElements: [Any]? {
- get {
- var elements = [Any]()
- elements.append(contentsOf: [titleLabel, textView])
-
- if showError {
- elements.append(statusIcon)
- if let errorText, !errorText.isEmpty {
- elements.append(errorLabel)
- }
- }
-
- if let helperText, !helperText.isEmpty {
- elements.append(helperLabel)
- }
-
- return elements
- }
-
- set { super.accessibilityElements = newValue }
- }
-
-
- open override var canBecomeFirstResponder: Bool {
- return textView.canBecomeFirstResponder
- }
-
- open override func becomeFirstResponder() -> Bool {
- return textView.becomeFirstResponder()
- }
-
- open override var canResignFirstResponder: Bool {
- return textView.canResignFirstResponder
- }
-
- open override func resignFirstResponder() -> Bool {
- return textView.resignFirstResponder()
- }
-
+
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json
index 28cfbca3..d8a92d8d 100644
--- a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json
+++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "discover.svg",
+ "filename" : "Discover-02.svg",
"idiom" : "universal"
}
],
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Discover-02.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Discover-02.svg
new file mode 100644
index 00000000..ea75afb4
--- /dev/null
+++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/Discover-02.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg
deleted file mode 100644
index a056ab58..00000000
--- a/VDS/SupportingFiles/Icons.xcassets/CreditCard/discover.imageset/discover.svg
+++ /dev/null
@@ -1,49 +0,0 @@
-
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json
index 8a4c248a..c4aba6fe 100644
--- a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json
+++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/Contents.json
@@ -1,7 +1,7 @@
{
"images" : [
{
- "filename" : "jcb.svg",
+ "filename" : "jcb-emblem-logo.svg",
"idiom" : "universal"
}
],
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb-emblem-logo.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb-emblem-logo.svg
new file mode 100644
index 00000000..4b8f6dd9
--- /dev/null
+++ b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb-emblem-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg b/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg
deleted file mode 100644
index ab197f4b..00000000
--- a/VDS/SupportingFiles/Icons.xcassets/CreditCard/jcb.imageset/jcb.svg
+++ /dev/null
@@ -1,51 +0,0 @@
-