added TextField
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
413d5567af
commit
bd50e75f85
@ -132,6 +132,7 @@
|
||||
EAD068922A560B65002E3A2D /* LoaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD068912A560B65002E3A2D /* LoaderViewController.swift */; };
|
||||
EAD068942A560C13002E3A2D /* LoaderLaunchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD068932A560C13002E3A2D /* LoaderLaunchable.swift */; };
|
||||
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
|
||||
EAE785352BA22825009428EA /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE785342BA22825009428EA /* TextField.swift */; };
|
||||
EAEEEC922B1F807300531FC2 /* BadgeChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = EAEEEC912B1F807300531FC2 /* BadgeChangeLog.txt */; };
|
||||
EAEEEC962B1F893B00531FC2 /* ButtonChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = EAEEEC952B1F893B00531FC2 /* ButtonChangeLog.txt */; };
|
||||
EAEEEC982B1F8DD100531FC2 /* LineChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = EAEEEC972B1F8DD100531FC2 /* LineChangeLog.txt */; };
|
||||
@ -303,6 +304,7 @@
|
||||
EAD068912A560B65002E3A2D /* LoaderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoaderViewController.swift; sourceTree = "<group>"; };
|
||||
EAD068932A560C13002E3A2D /* LoaderLaunchable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoaderLaunchable.swift; sourceTree = "<group>"; };
|
||||
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
|
||||
EAE785342BA22825009428EA /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
|
||||
EAEEEC912B1F807300531FC2 /* BadgeChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = BadgeChangeLog.txt; sourceTree = "<group>"; };
|
||||
EAEEEC952B1F893B00531FC2 /* ButtonChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ButtonChangeLog.txt; sourceTree = "<group>"; };
|
||||
EAEEEC972B1F8DD100531FC2 /* LineChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = LineChangeLog.txt; sourceTree = "<group>"; };
|
||||
@ -800,6 +802,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EAC925872911C9DE00091998 /* InputField.swift */,
|
||||
EAE785342BA22825009428EA /* TextField.swift */,
|
||||
);
|
||||
path = InputField;
|
||||
sourceTree = "<group>";
|
||||
@ -1053,6 +1056,7 @@
|
||||
EAD068922A560B65002E3A2D /* LoaderViewController.swift in Sources */,
|
||||
EABFEB642A26473700C4C106 /* NSAttributedString.swift in Sources */,
|
||||
EAF7F13328A2A16500B287F5 /* AttachmentLabelAttributeModel.swift in Sources */,
|
||||
EAE785352BA22825009428EA /* TextField.swift in Sources */,
|
||||
EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */,
|
||||
EA89200628B526D6006B9984 /* CheckboxGroup.swift in Sources */,
|
||||
EA8E40932A82889500934ED3 /* TooltipDialog.swift in Sources */,
|
||||
|
||||
@ -64,10 +64,7 @@ open class InputField: EntryFieldBase, UITextFieldDelegate {
|
||||
}
|
||||
|
||||
/// UITextField shown in the InputField.
|
||||
open var textField = UITextField().with {
|
||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||
$0.font = TextStyle.bodyLarge.font
|
||||
}
|
||||
open var textField = TextField()
|
||||
|
||||
/// Color configuration for the textField.
|
||||
open var textFieldTextColorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
||||
|
||||
253
VDS/Components/TextFields/InputField/TextField.swift
Normal file
253
VDS/Components/TextFields/InputField/TextField.swift
Normal file
@ -0,0 +1,253 @@
|
||||
//
|
||||
// TextField.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 3/13/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
import VDSColorTokens
|
||||
|
||||
@objc(VDSTextField)
|
||||
open class TextField: UITextField, ViewProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
required public init() {
|
||||
super.init(frame: .zero)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Combine Properties
|
||||
//--------------------------------------------------
|
||||
/// Set of Subscribers for any Publishers for this Control.
|
||||
open var subscribers = Set<AnyCancellable>()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
/// Key of whether or not updateView() is called in setNeedsUpdate()
|
||||
open var shouldUpdateView: Bool = true
|
||||
|
||||
open var surface: Surface = .light { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Array of LabelAttributeModel objects used in rendering the text.
|
||||
open var textAttributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// TextStyle used on the titleLabel.
|
||||
open var textStyle: TextStyle { .defaultStyle }
|
||||
|
||||
/// Will determine if a scaled font should be used for the titleLabel font.
|
||||
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() } }
|
||||
|
||||
open override var isEnabled: Bool { didSet { setNeedsUpdate() } }
|
||||
|
||||
open override var isSelected: Bool { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// State of animating isHighlight.
|
||||
public var isHighlighting = false
|
||||
|
||||
/// Whether the Control should handle the isHighlighted state.
|
||||
open var shouldHighlight: Bool { isHighlighting == false }
|
||||
|
||||
/// Whether the Control is highlighted or not.
|
||||
open override var isHighlighted: Bool {
|
||||
didSet {
|
||||
if shouldHighlight {
|
||||
isHighlighting = true
|
||||
setNeedsUpdate()
|
||||
isHighlighting = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open var textColorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
||||
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
|
||||
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
|
||||
}.eraseToAnyColorable(){ didSet { setNeedsUpdate() }}
|
||||
|
||||
open override var textColor: UIColor? {
|
||||
get { textColorConfiguration.getColor(self) }
|
||||
set { }
|
||||
}
|
||||
|
||||
private enum TextSetMode {
|
||||
case text
|
||||
case attributedText
|
||||
}
|
||||
|
||||
private var textSetMode: TextSetMode = .text
|
||||
|
||||
/// :nodoc:
|
||||
open override var text: String! {
|
||||
get { super.text }
|
||||
set {
|
||||
// When text is set, we may need to re-style it as attributedText
|
||||
// with the correct paragraph style to achieve the desired line height.
|
||||
textSetMode = .text
|
||||
styleText(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
open override var attributedText: NSAttributedString? {
|
||||
get { super.attributedText }
|
||||
set {
|
||||
// When text is set, we may need to re-style it as attributedText
|
||||
// with the correct paragraph style to achieve the desired line height.
|
||||
textSetMode = .attributedText
|
||||
styleAttributedText(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
open override var textAlignment: NSTextAlignment {
|
||||
didSet {
|
||||
if textAlignment != oldValue {
|
||||
// Text alignment can be part of our paragraph style, so we may need to
|
||||
// re-style when changed
|
||||
restyleText()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
open func initialSetup() {
|
||||
if !initialSetupPerformed {
|
||||
initialSetupPerformed = true
|
||||
backgroundColor = .clear
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
accessibilityCustomActions = []
|
||||
setup()
|
||||
setNeedsUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open func setup() {
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
open func updateView() {
|
||||
restyleText()
|
||||
}
|
||||
|
||||
open func updateAccessibility() {}
|
||||
|
||||
open func reset() {
|
||||
shouldUpdateView = false
|
||||
surface = .light
|
||||
text = nil
|
||||
accessibilityCustomActions = []
|
||||
shouldUpdateView = true
|
||||
setNeedsUpdate()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Overrides Methods
|
||||
//--------------------------------------------------
|
||||
/// :nodoc
|
||||
open override func textRect(forBounds bounds: CGRect) -> CGRect {
|
||||
super.textRect(forBounds: bounds).inset(by: textStyle.edgeInsets)
|
||||
}
|
||||
|
||||
/// :nodoc
|
||||
open override func editingRect(forBounds bounds: CGRect) -> CGRect {
|
||||
super.editingRect(forBounds: bounds).inset(by: textStyle.edgeInsets)
|
||||
}
|
||||
|
||||
/// :nodoc
|
||||
open override func clearButtonRect(forBounds bounds: CGRect) -> CGRect {
|
||||
super.clearButtonRect(forBounds: bounds).offsetBy(dx: -textStyle.edgeInsets.right, dy: 0)
|
||||
}
|
||||
|
||||
/// :nodoc
|
||||
open override func leftViewRect(forBounds bounds: CGRect) -> CGRect {
|
||||
super.leftViewRect(forBounds: bounds).offsetBy(dx: textStyle.edgeInsets.left, dy: 0)
|
||||
}
|
||||
|
||||
/// :nodoc
|
||||
open override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
|
||||
super.rightViewRect(forBounds: bounds).offsetBy(dx: -textStyle.edgeInsets.right, dy: 0)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Methods
|
||||
//--------------------------------------------------
|
||||
private func restyleText() {
|
||||
if textSetMode == .text {
|
||||
styleText(text)
|
||||
} else {
|
||||
styleAttributedText(attributedText)
|
||||
}
|
||||
}
|
||||
|
||||
private func styleText(_ newValue: String!) {
|
||||
defer { invalidateIntrinsicContentSize() }
|
||||
guard let newValue else {
|
||||
// We don't need to use attributed text
|
||||
super.attributedText = nil
|
||||
super.text = newValue
|
||||
return
|
||||
}
|
||||
|
||||
accessibilityCustomActions = []
|
||||
|
||||
//create the primary string
|
||||
let mutableText = NSMutableAttributedString.mutableText(for: newValue,
|
||||
textStyle: textStyle,
|
||||
useScaledFont: useScaledFont,
|
||||
textColor: textColorConfiguration.getColor(self),
|
||||
alignment: textAlignment,
|
||||
lineBreakMode: .byWordWrapping)
|
||||
|
||||
applyAttributes(mutableText)
|
||||
|
||||
// Set attributed text to match typography
|
||||
super.attributedText = mutableText
|
||||
|
||||
}
|
||||
|
||||
private func styleAttributedText(_ newValue: NSAttributedString?) {
|
||||
defer { invalidateIntrinsicContentSize() }
|
||||
guard let newValue = newValue else {
|
||||
// We don't need any additional styling
|
||||
super.attributedText = newValue
|
||||
return
|
||||
}
|
||||
|
||||
let mutableText = NSMutableAttributedString(attributedString: newValue)
|
||||
|
||||
applyAttributes(mutableText)
|
||||
|
||||
// Modify attributed text to match typography
|
||||
super.attributedText = mutableText
|
||||
}
|
||||
|
||||
private func applyAttributes(_ mutableAttributedString: NSMutableAttributedString) {
|
||||
if let textAttributes {
|
||||
mutableAttributedString.apply(attributes: textAttributes)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user