continues development
This commit is contained in:
parent
63cf1c994a
commit
3efe4ae81f
@ -87,7 +87,7 @@ import UIKit
|
|||||||
dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData)
|
dropDownCaretView.setOptional(with: model.caretView, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func dismissFieldInput(_ sender: Any?) {
|
@objc public override func dismissFieldInput(_ sender: Any?) {
|
||||||
performDropdownAction()
|
performDropdownAction()
|
||||||
super.dismissFieldInput(sender)
|
super.dismissFieldInput(sender)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,10 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
open class BaseItemPickerEntryField: BaseDropdownEntryField {
|
public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)
|
||||||
|
|
||||||
|
|
||||||
|
open class BaseItemPickerEntryField: BaseDropdownEntryField, UIPickerViewDelegate, UIPickerViewDataSource {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Outlets
|
// MARK: - Outlets
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -27,4 +30,31 @@ open class BaseItemPickerEntryField: BaseDropdownEntryField {
|
|||||||
|
|
||||||
/// When selecting for first responder, allow initial selected value to appear in empty text field.
|
/// When selecting for first responder, allow initial selected value to appear in empty text field.
|
||||||
public var setInitialValueInTextField = true
|
public var setInitialValueInTextField = true
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
||||||
|
super.setupFieldContainerContent(container)
|
||||||
|
|
||||||
|
pickerView = UIPickerView.addPicker(to: self.textField, delegate: self, dismissAction: #selector(dismissFieldInput))
|
||||||
|
textField.hideBlinkingCaret = true
|
||||||
|
textField.autocorrectionType = .no
|
||||||
|
uiTextFieldDelegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) {
|
||||||
|
|
||||||
|
pickerView?.delegate = delegate
|
||||||
|
pickerView?.dataSource = delegate
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Picker Delegate to Override
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 0 }
|
||||||
|
|
||||||
|
public func numberOfComponents(in pickerView: UIPickerView) -> Int { 0 }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,25 +8,13 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public typealias TextFieldAndPickerDelegate = (UITextFieldDelegate & UIPickerViewDelegate & UIPickerViewDataSource)
|
|
||||||
|
|
||||||
|
open class ItemDropdownEntryField: BaseItemPickerEntryField {
|
||||||
open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open var pickerData: [String] = []
|
open var pickerData: [String] = []
|
||||||
open var pickerView: UIPickerView?
|
|
||||||
|
|
||||||
/// When selecting for first responder, allow initial selected value to appear in empty text field.
|
|
||||||
public var setInitialValueInTextField = true
|
|
||||||
|
|
||||||
/// Closure passed here will run as picker changes items.
|
|
||||||
public var observeDropdownChange: ((String, String)->())?
|
|
||||||
|
|
||||||
/// Closure passed here will run upon dismissing the selection picker.
|
|
||||||
public var observeDropdownSelection: ((String)->())?
|
|
||||||
|
|
||||||
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
|
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
|
||||||
model as? ItemDropdownEntryFieldModel
|
model as? ItemDropdownEntryFieldModel
|
||||||
@ -61,21 +49,6 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
|
||||||
super.setupFieldContainerContent(container)
|
|
||||||
|
|
||||||
pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput))
|
|
||||||
textField.hideBlinkingCaret = true
|
|
||||||
textField.autocorrectionType = .no
|
|
||||||
uiTextFieldDelegate = self
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) {
|
|
||||||
|
|
||||||
pickerView?.delegate = delegate
|
|
||||||
pickerView?.dataSource = delegate
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the textField with the first value of the available picker data.
|
/// Sets the textField with the first value of the available picker data.
|
||||||
@objc private func setInitialValueFromPicker() {
|
@objc private func setInitialValueFromPicker() {
|
||||||
|
|
||||||
@ -116,14 +89,14 @@ open class ItemDropdownEntryField: BaseDropdownEntryField {
|
|||||||
self.pickerView(pickerView, didSelectRow: index, inComponent: 0)
|
self.pickerView(pickerView, didSelectRow: index, inComponent: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:- Base Picker Delegate
|
//--------------------------------------------------
|
||||||
extension ItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
// MARK: - Picker Delegate
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
|
@objc public override func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
|
||||||
|
|
||||||
@objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
@objc public override func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||||
pickerData.count
|
pickerData.count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,21 +52,6 @@ open class MultiItemDropdownEntryField: BaseItemPickerEntryField {
|
|||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc open override func setupFieldContainerContent(_ container: UIView) {
|
|
||||||
super.setupFieldContainerContent(container)
|
|
||||||
|
|
||||||
pickerView = UIPickerView.addPicker(to: textField, delegate: self, dismissAction: #selector(dismissFieldInput))
|
|
||||||
textField.hideBlinkingCaret = true
|
|
||||||
textField.autocorrectionType = .no
|
|
||||||
uiTextFieldDelegate = self
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc public func setPickerDelegates(delegate: UIPickerViewDelegate & UIPickerViewDataSource) {
|
|
||||||
|
|
||||||
pickerView?.delegate = delegate
|
|
||||||
pickerView?.dataSource = delegate
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the textField with the first value of the available picker data.
|
/// Sets the textField with the first value of the available picker data.
|
||||||
@objc private func setInitialValueFromPicker() {
|
@objc private func setInitialValueFromPicker() {
|
||||||
|
|
||||||
@ -75,7 +60,7 @@ open class MultiItemDropdownEntryField: BaseItemPickerEntryField {
|
|||||||
let rowText = dropdownModel?.selectedRowText
|
let rowText = dropdownModel?.selectedRowText
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
// observeDropdownChange?(text ?? "", rowText)
|
observeDropdownChange?(text ?? "", rowText)
|
||||||
text = rowText
|
text = rowText
|
||||||
|
|
||||||
for component in 0..<componentCount {
|
for component in 0..<componentCount {
|
||||||
@ -103,7 +88,7 @@ open class MultiItemDropdownEntryField: BaseItemPickerEntryField {
|
|||||||
let rowText = dropdownModel?.selectedRowText
|
let rowText = dropdownModel?.selectedRowText
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
// observeDropdownSelection?(rowText)
|
observeDropdownSelection?(rowText)
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -123,14 +108,14 @@ open class MultiItemDropdownEntryField: BaseItemPickerEntryField {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MARK:- Picker Delegate
|
//--------------------------------------------------
|
||||||
extension MultiItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSource {
|
// MARK: - Picker Delegate
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
@objc public func numberOfComponents(in pickerView: UIPickerView) -> Int { componentCount }
|
@objc public override func numberOfComponents(in pickerView: UIPickerView) -> Int { componentCount }
|
||||||
|
|
||||||
@objc public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
@objc public override func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
|
||||||
pickerComponents[component].count
|
pickerComponents[component].count
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +135,7 @@ extension MultiItemDropdownEntryField: UIPickerViewDelegate, UIPickerViewDataSou
|
|||||||
let rowText = dropdownModel?.selectedRowText
|
let rowText = dropdownModel?.selectedRowText
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
// observeDropdownChange?(text ?? "", rowText)
|
observeDropdownChange?(text ?? "", rowText)
|
||||||
text = rowText
|
text = rowText
|
||||||
dropdownModel?.selectedIndexes[component] = row
|
dropdownModel?.selectedIndexes[component] = row
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import Foundation
|
|||||||
|
|
||||||
public var components: [[String]] = [[]]
|
public var components: [[String]] = [[]]
|
||||||
public var selectedIndexes: [Int: Int] = [:]
|
public var selectedIndexes: [Int: Int] = [:]
|
||||||
|
public var delimiters: [String]?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Validation
|
// MARK: - Validation
|
||||||
@ -37,6 +38,12 @@ import Foundation
|
|||||||
|
|
||||||
for i in 0..<components.count {
|
for i in 0..<components.count {
|
||||||
let pickerIndex = selectedIndexes[i] ?? 0
|
let pickerIndex = selectedIndexes[i] ?? 0
|
||||||
|
if i < components.count, let delimiters = delimiters {
|
||||||
|
text += components[i][pickerIndex] + delimiters[pickerIndex]
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
text += components[i][pickerIndex] + (i == components.count - 1 ? "" : " ")
|
text += components[i][pickerIndex] + (i == components.count - 1 ? "" : " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,8 +68,8 @@ import Foundation
|
|||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case components
|
case components
|
||||||
case selectedIndex // Deprecated: for backwards compatability
|
|
||||||
case selectedIndexes
|
case selectedIndexes
|
||||||
|
case delimiters
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -74,9 +81,10 @@ import Foundation
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
components = try typeContainer.decode([[String]].self, forKey: .components)
|
components = try typeContainer.decode([[String]].self, forKey: .components)
|
||||||
|
delimiters = try typeContainer.decodeIfPresent([String].self, forKey: .delimiters)
|
||||||
|
|
||||||
if let indicies = try typeContainer.decodeIfPresent([Int].self, forKey: .selectedIndexes) {
|
if let indexes = try typeContainer.decodeIfPresent([Int].self, forKey: .selectedIndexes) {
|
||||||
for (component, index) in indicies.enumerated() {
|
for (component, index) in indexes.enumerated() {
|
||||||
self.selectedIndexes[component] = index
|
self.selectedIndexes[component] = index
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,5 +97,6 @@ import Foundation
|
|||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(components, forKey: .components)
|
try container.encode(components, forKey: .components)
|
||||||
try container.encode(selectedIndexesArray, forKey: .selectedIndexes)
|
try container.encode(selectedIndexesArray, forKey: .selectedIndexes)
|
||||||
|
try container.encodeIfPresent(delimiters, forKey: .delimiters)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,9 @@
|
|||||||
//
|
//
|
||||||
// Form fields are items can be interacted with. They have value, and may need to be validated.
|
// Form fields are items can be interacted with. They have value, and may need to be validated.
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
|
|
||||||
public protocol FormFieldProtocol: FormItemProtocol {
|
public protocol FormFieldProtocol: FormItemProtocol {
|
||||||
|
|
||||||
/// How the validator identifies the field when validating rules.
|
/// How the validator identifies the field when validating rules.
|
||||||
var fieldKey: String? { get set }
|
var fieldKey: String? { get set }
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user