refactored code
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
ce3d9e6e22
commit
417cddb382
@ -10,9 +10,10 @@ import UIKit
|
|||||||
import VDSCoreTokens
|
import VDSCoreTokens
|
||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
/// A stepper is a two-segment control that people use to increase or decrease an incremental value.
|
/// A stepper is a two-segment control that people use to increase or decrease an incremental value.'
|
||||||
|
@objcMembers
|
||||||
@objc(VDSInputStepper)
|
@objc(VDSInputStepper)
|
||||||
open class InputStepper: EntryFieldBase {
|
open class InputStepper: EntryFieldBase<Int> {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -35,6 +36,29 @@ open class InputStepper: EntryFieldBase {
|
|||||||
/// Enum used to describe the size of Input Stepper.
|
/// Enum used to describe the size of Input Stepper.
|
||||||
public enum Size: String, CaseIterable {
|
public enum Size: String, CaseIterable {
|
||||||
case large, small
|
case large, small
|
||||||
|
|
||||||
|
var minWidth: CGFloat {
|
||||||
|
self == .large ? 121 : 90
|
||||||
|
}
|
||||||
|
|
||||||
|
var minHeight: CGFloat {
|
||||||
|
self == .large ? 44 : 32
|
||||||
|
}
|
||||||
|
|
||||||
|
var space: CGFloat {
|
||||||
|
self == .large ? VDSLayout.space3X : VDSLayout.space2X
|
||||||
|
}
|
||||||
|
var padding: CGFloat {
|
||||||
|
self == .large ? 6.0 : VDSLayout.space1X
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonContainerSize: Int {
|
||||||
|
self == .large ? 32 : 24
|
||||||
|
}
|
||||||
|
|
||||||
|
var textStyle: TextStyle {
|
||||||
|
self == .large ? .boldBodyLarge : .boldBodySmall
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enum used to describe the width of a fixed value or percentage of the input stepper control.
|
/// Enum used to describe the width of a fixed value or percentage of the input stepper control.
|
||||||
@ -81,21 +105,36 @@ open class InputStepper: EntryFieldBase {
|
|||||||
/// Allows an id to be passed to input stepper.
|
/// Allows an id to be passed to input stepper.
|
||||||
open var id: Int? { didSet { setNeedsUpdate() } }
|
open var id: Int? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
private var _defaultValue: Int = 0
|
||||||
|
open override var defaultValue: Int? {
|
||||||
|
get { _defaultValue }
|
||||||
|
set {
|
||||||
|
if let newValue {
|
||||||
|
_defaultValue = newValue > maxValue ? maxValue : newValue < minValue ? minValue : newValue
|
||||||
|
} else {
|
||||||
|
_defaultValue = 0
|
||||||
|
}
|
||||||
|
setNeedsUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open override var value: Int? { return defaultValue }
|
||||||
|
|
||||||
/// Maximum value of the input stepper, defaults to '99'.
|
/// Maximum value of the input stepper, defaults to '99'.
|
||||||
open var maxValue: Int? = 99 {
|
lazy open var maxValue: Int = { _defaultMaxValue }() {
|
||||||
didSet {
|
didSet {
|
||||||
if let value = maxValue, value > 99 || value < 0 {
|
if maxValue > _defaultMaxValue || maxValue < _defaultMinValue && maxValue > minValue {
|
||||||
maxValue = 99
|
maxValue = _defaultMaxValue
|
||||||
}
|
}
|
||||||
setNeedsUpdate()
|
setNeedsUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Minimum value of the input stepper, defaults to '0'.
|
/// Minimum value of the input stepper, defaults to '0'.
|
||||||
open var minValue: Int? = 0 {
|
lazy open var minValue: Int = { _defaultMinValue }() {
|
||||||
didSet {
|
didSet {
|
||||||
if let value = minValue, value < 0 && value >= 99 {
|
if minValue < _defaultMinValue && minValue >= _defaultMaxValue && minValue < maxValue {
|
||||||
minValue = 0
|
minValue = _defaultMinValue
|
||||||
}
|
}
|
||||||
setNeedsUpdate()
|
setNeedsUpdate()
|
||||||
}
|
}
|
||||||
@ -112,21 +151,12 @@ open class InputStepper: EntryFieldBase {
|
|||||||
/// Accepts any text or character to appear next to input stepper value.
|
/// Accepts any text or character to appear next to input stepper value.
|
||||||
open var trailingText: String? { didSet { setNeedsUpdate() } }
|
open var trailingText: String? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
/// Value for the textField
|
|
||||||
open override var value: String? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private var _controlWidth: ControlWidth? = nil
|
private var _controlWidth: ControlWidth? = nil
|
||||||
|
private var _defaultMinValue: Int = 0
|
||||||
/// Default Int value of the input stepper, defaults to '0'.
|
private var _defaultMaxValue: Int = 99
|
||||||
internal var defaultIntValue: Int {
|
|
||||||
guard let intValue = defaultValue as? Int else { return 0 }
|
|
||||||
return intValue
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is the view that will be wrapped with the border for userInteraction.
|
/// This is the view that will be wrapped with the border for userInteraction.
|
||||||
/// The only subview of this view is the stepperStackView.
|
/// The only subview of this view is the stepperStackView.
|
||||||
@ -177,28 +207,21 @@ open class InputStepper: EntryFieldBase {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Configuration Properties
|
// MARK: - Configuration Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
internal override var containerSize: CGSize { CGSize(width: size == .large ? largeMinWidth : smallMinWidth, height: size == .large ? largeMinHeight : smallMinHeight) }
|
internal override var containerSize: CGSize { CGSize(width: size.minWidth, height: size.minHeight) }
|
||||||
|
|
||||||
internal var largeMinWidth = 121
|
|
||||||
internal var smallMinWidth = 90
|
|
||||||
internal var largeMinHeight = 44
|
|
||||||
internal var smallMinHeight = 32
|
|
||||||
|
|
||||||
internal let labelColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
internal let labelColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||||
internal let labelDisabledColorConfiguration = SurfaceColorConfiguration(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark)
|
internal let labelDisabledColorConfiguration = SurfaceColorConfiguration(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark)
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
open override func initialSetup() {
|
|
||||||
super.initialSetup()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
|
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
|
||||||
open override func setup() {
|
open override func setup() {
|
||||||
super.setup()
|
super.setup()
|
||||||
|
|
||||||
// Set initial states
|
// Set initial states
|
||||||
|
defaultValue = 0
|
||||||
containerView.isEnabled = false
|
containerView.isEnabled = false
|
||||||
statusIcon.isHidden = true
|
statusIcon.isHidden = true
|
||||||
|
|
||||||
@ -216,12 +239,11 @@ open class InputStepper: EntryFieldBase {
|
|||||||
stepperStackView.addArrangedSubview(incrementButton)
|
stepperStackView.addArrangedSubview(incrementButton)
|
||||||
|
|
||||||
// Set space between decrement button, label, and increment button relative to input Stepper size.
|
// Set space between decrement button, label, and increment button relative to input Stepper size.
|
||||||
let space = size == .large ? VDSLayout.space3X : VDSLayout.space2X
|
stepperStackView.setCustomSpacing(size.space, after: decrementButton)
|
||||||
stepperStackView.setCustomSpacing(space, after: decrementButton)
|
stepperStackView.setCustomSpacing(size.space, after: textLabel)
|
||||||
stepperStackView.setCustomSpacing(space, after: textLabel)
|
|
||||||
|
|
||||||
// Update Edge insets relative to input Stepper size.
|
// Update Edge insets relative to input Stepper size.
|
||||||
stepperStackView.pinToSuperView(.uniform(size == .large ? 6.0 : VDSLayout.space1X))
|
stepperStackView.pinToSuperView(.uniform(size.padding))
|
||||||
|
|
||||||
// stepperContainerView for controls in EntryFieldBase.controlContainerView
|
// stepperContainerView for controls in EntryFieldBase.controlContainerView
|
||||||
stepperContainerView.addSubview(stepperStackView)
|
stepperContainerView.addSubview(stepperStackView)
|
||||||
@ -240,8 +262,8 @@ open class InputStepper: EntryFieldBase {
|
|||||||
statusIcon.isHidden = true
|
statusIcon.isHidden = true
|
||||||
|
|
||||||
// Update label text, style, color, ande surface.
|
// Update label text, style, color, ande surface.
|
||||||
textLabel.text = String(defaultIntValue) + " " + (trailingText ?? "")
|
textLabel.text = "\(_defaultValue) " + (trailingText ?? "")
|
||||||
textLabel.textStyle = size == .large ? .boldBodyLarge : .boldBodySmall
|
textLabel.textStyle = size.textStyle
|
||||||
textLabel.textColorConfiguration = !isEnabled ? labelDisabledColorConfiguration.eraseToAnyColorable() : labelColorConfiguration.eraseToAnyColorable()
|
textLabel.textColorConfiguration = !isEnabled ? labelDisabledColorConfiguration.eraseToAnyColorable() : labelColorConfiguration.eraseToAnyColorable()
|
||||||
textLabel.surface = surface
|
textLabel.surface = surface
|
||||||
|
|
||||||
@ -287,8 +309,9 @@ open class InputStepper: EntryFieldBase {
|
|||||||
controlWidth = nil
|
controlWidth = nil
|
||||||
widthPercentage = nil
|
widthPercentage = nil
|
||||||
id = nil
|
id = nil
|
||||||
minValue = 0
|
defaultValue = 0
|
||||||
maxValue = 99
|
minValue = _defaultMinValue
|
||||||
|
maxValue = _defaultMaxValue
|
||||||
trailingText = nil
|
trailingText = nil
|
||||||
size = .large
|
size = .large
|
||||||
helperTextPlacement = .bottom
|
helperTextPlacement = .bottom
|
||||||
@ -325,27 +348,23 @@ open class InputStepper: EntryFieldBase {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Methods
|
// MARK: - Private Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
internal func checkDefaultValue() {
|
internal func decrementButtonClick() {
|
||||||
if let minValue, let maxValue {
|
if _defaultValue > minValue {
|
||||||
defaultValue = defaultIntValue > maxValue ? maxValue : defaultIntValue < minValue ? minValue : defaultIntValue
|
defaultValue = _defaultValue - 1
|
||||||
|
sendActions(for: .valueChanged)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func decrementButtonClick() {
|
|
||||||
defaultValue = defaultIntValue - 1
|
|
||||||
checkDefaultValue()
|
|
||||||
updateButtonStates()
|
|
||||||
}
|
|
||||||
|
|
||||||
internal func incrementButtonClick() {
|
internal func incrementButtonClick() {
|
||||||
defaultValue = defaultIntValue + 1
|
if _defaultValue < maxValue {
|
||||||
checkDefaultValue()
|
defaultValue = _defaultValue + 1
|
||||||
updateButtonStates()
|
sendActions(for: .valueChanged)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func updateButtonStates() {
|
internal func updateButtonStates() {
|
||||||
decrementButton.customContainerSize = size == .large ? 32 : 24
|
decrementButton.customContainerSize = size.buttonContainerSize
|
||||||
incrementButton.customContainerSize = size == .large ? 32 : 24
|
incrementButton.customContainerSize = size.buttonContainerSize
|
||||||
decrementButton.surface = surface
|
decrementButton.surface = surface
|
||||||
incrementButton.surface = surface
|
incrementButton.surface = surface
|
||||||
|
|
||||||
@ -353,8 +372,8 @@ open class InputStepper: EntryFieldBase {
|
|||||||
decrementButton.isEnabled = false
|
decrementButton.isEnabled = false
|
||||||
incrementButton.isEnabled = false
|
incrementButton.isEnabled = false
|
||||||
} else {
|
} else {
|
||||||
decrementButton.isEnabled = defaultIntValue > minValue ?? 0 ? true : false
|
decrementButton.isEnabled = (defaultValue ?? _defaultMaxValue ) > minValue ? true : false
|
||||||
incrementButton.isEnabled = defaultIntValue < maxValue ?? 99 ? true : false
|
incrementButton.isEnabled = (defaultValue ?? _defaultMinValue) < maxValue ? true : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +384,7 @@ open class InputStepper: EntryFieldBase {
|
|||||||
// Update Edge insets if size changes applied.
|
// Update Edge insets if size changes applied.
|
||||||
stepperStackView.removeFromSuperview()
|
stepperStackView.removeFromSuperview()
|
||||||
stepperContainerView.addSubview(stepperStackView)
|
stepperContainerView.addSubview(stepperStackView)
|
||||||
stepperStackView.pinToSuperView(.uniform(size == .large ? 6.0 : VDSLayout.space1X))
|
stepperStackView.pinToSuperView(.uniform(size.padding))
|
||||||
|
|
||||||
// Update height if size changes applied.
|
// Update height if size changes applied.
|
||||||
stepperHeightConstraint?.deactivate()
|
stepperHeightConstraint?.deactivate()
|
||||||
@ -407,7 +426,7 @@ open class InputStepper: EntryFieldBase {
|
|||||||
|
|
||||||
// Update the container view width based on the percentage received.
|
// Update the container view width based on the percentage received.
|
||||||
private func updateContainerWidthWithPercentage() {
|
private func updateContainerWidthWithPercentage() {
|
||||||
guard let superWidth = superview?.frame.width else {
|
guard let superWidth = horizontalPinnedWidth() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +434,6 @@ open class InputStepper: EntryFieldBase {
|
|||||||
if let widthPercentage {
|
if let widthPercentage {
|
||||||
// test value vs minimum width and take the greater value
|
// test value vs minimum width and take the greater value
|
||||||
width = max(superWidth * (widthPercentage / 100), minWidth)
|
width = max(superWidth * (widthPercentage / 100), minWidth)
|
||||||
updateContainerWidth()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user