generall stable
This commit is contained in:
parent
efe3f95746
commit
7f6bcfc712
@ -70,7 +70,6 @@
|
||||
0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */; };
|
||||
0A25209624645AFD000FA9F6 /* TextViewEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */; };
|
||||
0A25209824645B76000FA9F6 /* TextViewEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */; };
|
||||
0A2520A924646230000FA9F6 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2520A824646230000FA9F6 /* TextViewModel.swift */; };
|
||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
|
||||
0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; };
|
||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; };
|
||||
@ -479,7 +478,6 @@
|
||||
0A21DB93235E24ED00C160A2 /* DigitEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitEntryField.swift; sourceTree = "<group>"; };
|
||||
0A25209524645AFD000FA9F6 /* TextViewEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryField.swift; sourceTree = "<group>"; };
|
||||
0A25209724645B76000FA9F6 /* TextViewEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewEntryFieldModel.swift; sourceTree = "<group>"; };
|
||||
0A2520A824646230000FA9F6 /* TextViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewModel.swift; sourceTree = "<group>"; };
|
||||
0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = "<group>"; };
|
||||
0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
|
||||
0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1765,7 +1763,6 @@
|
||||
D264FAA92440F97600D98315 /* CollectionView.swift */,
|
||||
0A5D59C323AD488600EFD9E9 /* Protocols */,
|
||||
0A7918F423F5E7EA00772FF4 /* ImageView.swift */,
|
||||
0A2520A824646230000FA9F6 /* TextViewModel.swift */,
|
||||
);
|
||||
path = BaseClasses;
|
||||
sourceTree = "<group>";
|
||||
@ -2028,7 +2025,6 @@
|
||||
014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */,
|
||||
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
|
||||
D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */,
|
||||
0A2520A924646230000FA9F6 /* TextViewModel.swift in Sources */,
|
||||
94C2D9A723872DA90006CF46 /* LabelAttributeColorModel.swift in Sources */,
|
||||
943820842432382400B43AF3 /* WebView.swift in Sources */,
|
||||
0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */,
|
||||
|
||||
@ -69,6 +69,11 @@ import UIKit
|
||||
get { return entryFieldContainer.showError }
|
||||
set (error) {
|
||||
self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback
|
||||
if error {
|
||||
feedbackLabel.textColor = entryFieldModel?.errorTextColor?.uiColor ?? .mvmBlack
|
||||
} else {
|
||||
feedbackLabel.textColor = .mvmBlack
|
||||
}
|
||||
self.entryFieldContainer.showError = error
|
||||
self.entryFieldModel?.showError = error
|
||||
}
|
||||
@ -215,11 +220,10 @@ import UIKit
|
||||
entryFieldContainer.refreshUI()
|
||||
}
|
||||
|
||||
/**
|
||||
Method to override.
|
||||
Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
||||
*/
|
||||
@objc open func setupFieldContainerContent(_ container: UIView) { }
|
||||
/// Intended to add the interactive content (i.e. textField) to the entryFieldContainer.
|
||||
@objc open func setupFieldContainerContent(_ container: UIView) {
|
||||
// To Be Overriden
|
||||
}
|
||||
|
||||
@objc open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
public var placeholder: String?
|
||||
public var enabledTextColor: Color = Color(uiColor: .mvmBlack)
|
||||
public var disabledTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var textAlignment: NSTextAlignment = .left
|
||||
public var type: EntryType?
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -39,6 +40,7 @@
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case placeholder
|
||||
case textAlignment
|
||||
case enabledTextColor
|
||||
case disabledTextColor
|
||||
case type
|
||||
@ -51,6 +53,7 @@
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder)
|
||||
type = try typeContainer.decodeIfPresent(EntryType.self, forKey: .type)
|
||||
|
||||
@ -61,12 +64,17 @@
|
||||
if let disabledTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledTextColor) {
|
||||
self.disabledTextColor = disabledTextColor
|
||||
}
|
||||
|
||||
if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) {
|
||||
self.textAlignment = textAlignment
|
||||
}
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(placeholder, forKey: .placeholder)
|
||||
try container.encodeIfPresent(textAlignment, forKey: .textAlignment)
|
||||
try container.encode(enabledTextColor, forKey: .enabledTextColor)
|
||||
try container.encode(disabledTextColor, forKey: .disabledTextColor)
|
||||
try container.encodeIfPresent(type, forKey: .type)
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -27,101 +27,63 @@ class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
}()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Validate on each entry in the textField. Default: true
|
||||
public var validateEachCharacter: Bool = true
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Validate on each entry in the textField. Default: true
|
||||
public var validateEachCharacter: Bool = true
|
||||
|
||||
private var observingForChange: Bool = false
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var textViewEntryFieldModel: TextViewEntryFieldModel? {
|
||||
return model as? TextViewEntryFieldModel
|
||||
}
|
||||
|
||||
public override var isEnabled: Bool {
|
||||
get { return super.isEnabled }
|
||||
set (enabled) {
|
||||
super.isEnabled = enabled
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.textView.isEnabled = enabled
|
||||
self.textView.textColor = enabled ? self.textEntryFieldModel?.enabledTextColor.uiColor : self.textEntryFieldModel?.disabledTextColor.uiColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override var showError: Bool {
|
||||
get { return super.showError }
|
||||
set (error) {
|
||||
|
||||
if error {
|
||||
textView.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textView_error_message") ?? "", textView.text ?? "", entryFieldModel?.errorMessage ?? "")
|
||||
} else {
|
||||
textView.accessibilityValue = nil
|
||||
}
|
||||
|
||||
if textView.isSecureTextEntry {
|
||||
// showErrorView(error)
|
||||
}
|
||||
|
||||
super.showError = error
|
||||
}
|
||||
}
|
||||
|
||||
/// The text of this textView.
|
||||
open override var text: String? {
|
||||
get { return textView.text }
|
||||
set {
|
||||
textView.text = newValue
|
||||
textViewEntryFieldModel?.text = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Placeholder access for the textView.
|
||||
public var placeholder: String? {
|
||||
get {
|
||||
// return textView.placeholder
|
||||
return textViewEntryFieldModel?.placeholder
|
||||
}
|
||||
set {
|
||||
// textView.placeholder = newValue
|
||||
textViewEntryFieldModel?.placeholder = newValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Executes on UITextField.textDidBeginEditingNotification
|
||||
@objc func startEditing() {
|
||||
isSelected = true
|
||||
textView.becomeFirstResponder()
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidChangeNotification (each character entry)
|
||||
@objc func valueChanged() {
|
||||
guard validateEachCharacter else { return }
|
||||
isSelected = true
|
||||
validateTextField()
|
||||
}
|
||||
|
||||
/// Validates the text of the entry field.
|
||||
@objc public func validateTextField() {
|
||||
text = textField.text
|
||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidEndEditingNotification
|
||||
@objc func endInputing() {
|
||||
resignFirstResponder()
|
||||
if isValid {
|
||||
showError = false
|
||||
entryFieldContainer.bottomBar?.backgroundColor = UIColor.mvmBlack.cgColor
|
||||
public override var isEnabled: Bool {
|
||||
get { return super.isEnabled }
|
||||
set (enabled) {
|
||||
super.isEnabled = enabled
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.textView.isEnabled = enabled
|
||||
self.textView.textColor = enabled ? self.textViewEntryFieldModel?.enabledTextColor.uiColor : self.textViewEntryFieldModel?.disabledTextColor.uiColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func dismissFieldInput(_ sender: Any?) {
|
||||
resignFirstResponder()
|
||||
public override var showError: Bool {
|
||||
get { return super.showError }
|
||||
set (error) {
|
||||
|
||||
if error {
|
||||
textView.accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "textView_error_message") ?? "", textView.text ?? "", entryFieldModel?.errorMessage ?? "")
|
||||
} else {
|
||||
textView.accessibilityValue = nil
|
||||
}
|
||||
|
||||
super.showError = error
|
||||
}
|
||||
}
|
||||
|
||||
/// The text of this textView.
|
||||
open override var text: String? {
|
||||
get { return textView.text }
|
||||
set {
|
||||
textView.text = newValue
|
||||
textViewEntryFieldModel?.text = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Placeholder access for the textView.
|
||||
public var placeholder: String? {
|
||||
get { return textViewEntryFieldModel?.placeholder }
|
||||
set { textViewEntryFieldModel?.placeholder = newValue }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -158,6 +120,17 @@ class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
set { textView.delegate = newValue }
|
||||
}
|
||||
|
||||
@objc public func setBothTextDelegates(to delegate: (UITextViewDelegate & ObservingTextFieldDelegate)?) {
|
||||
observingTextFieldDelegate = delegate
|
||||
uiTextViewDelegate = delegate
|
||||
}
|
||||
|
||||
open func setupTextViewToolbar() {
|
||||
let observingDelegate = observingTextFieldDelegate ?? self
|
||||
textView.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
action: #selector(observingDelegate.dismissFieldInput))
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
//--------------------------------------------------
|
||||
@ -200,6 +173,45 @@ class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
heightConstraint?.constant = 0
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Executes on UITextField.textDidBeginEditingNotification
|
||||
@objc func startEditing() {
|
||||
isSelected = true
|
||||
textView.becomeFirstResponder()
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidChangeNotification (each character entry)
|
||||
@objc func valueChanged() {
|
||||
guard validateEachCharacter else { return }
|
||||
isSelected = true
|
||||
validateTextField()
|
||||
}
|
||||
|
||||
/// Validates the text of the entry field.
|
||||
@objc public func validateTextField() {
|
||||
text = textView.text
|
||||
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
|
||||
}
|
||||
|
||||
/// Executes on UITextField.textDidEndEditingNotification
|
||||
@objc func endInputing() {
|
||||
resignFirstResponder()
|
||||
if isValid {
|
||||
showError = false
|
||||
entryFieldContainer.bottomBar?.backgroundColor = UIColor.mvmBlack.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func dismissFieldInput(_ sender: Any?) {
|
||||
resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.set(with: model, delegateObject, additionalData)
|
||||
@ -211,10 +223,6 @@ class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
guard let model = model as? TextViewEntryFieldModel else { return }
|
||||
|
||||
heightConstraint?.constant = model.height ?? 0
|
||||
|
||||
// textView.isEditable = model.editable
|
||||
textView.textAlignment = model.textAlignment
|
||||
textView.textColor = model.enabledTextColor.uiColor
|
||||
text = model.text
|
||||
uiTextViewDelegate = delegateObject?.uiTextViewDelegate
|
||||
|
||||
@ -222,25 +230,30 @@ class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
accessibilityLabel = accessibilityText
|
||||
}
|
||||
|
||||
textView.isEditable = model.editable
|
||||
textView.textAlignment = model.textAlignment
|
||||
textView.textColor = model.enabled ? model.enabledTextColor.uiColor : model.disabledTextColor.uiColor
|
||||
textView.font = model.fontStyle.getFont()
|
||||
textView.setPlaceholderIfAvailable()
|
||||
|
||||
switch model.type {
|
||||
case .secure, .password:
|
||||
textView.isSecureTextEntry = true
|
||||
|
||||
case .number:
|
||||
textView.keyboardType = .numberPad
|
||||
|
||||
case .email:
|
||||
textView.keyboardType = .emailAddress
|
||||
default:
|
||||
break
|
||||
|
||||
default: break
|
||||
}
|
||||
|
||||
textView.font = model.fontStyle.getFont()
|
||||
textView.setPlaceholderIfAvailable()
|
||||
|
||||
if textView.isEditable {
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
let observingDelegate = delegateObject?.uiTextViewDelegate ?? self
|
||||
textView.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
action: #selector(textView.dismissFieldInput))
|
||||
action: #selector(textView.dismissFieldInput))
|
||||
|
||||
if (model.selected ?? false) && !model.wasInitiallySelected {
|
||||
model.wasInitiallySelected = true
|
||||
|
||||
@ -21,9 +21,10 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
public var accessibilityText: String?
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall
|
||||
public var height: CGFloat?
|
||||
public var textAlignment: NSTextAlignment = .left
|
||||
public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro
|
||||
public var editable: Bool = true
|
||||
public var showsPlaceholder: Bool = false
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
@ -33,7 +34,6 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
case text
|
||||
case accessibilityText
|
||||
case fontStyle
|
||||
case textAlignment
|
||||
case height
|
||||
case placeholderFontStyle
|
||||
case placeholderTextColor
|
||||
@ -56,10 +56,6 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
self.placeholderTextColor = placeholderTextColor
|
||||
}
|
||||
|
||||
if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) {
|
||||
self.textAlignment = textAlignment
|
||||
}
|
||||
|
||||
if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) {
|
||||
self.fontStyle = fontStyle
|
||||
}
|
||||
@ -77,7 +73,5 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle)
|
||||
try container.encode(placeholderTextColor, forKey: .placeholderTextColor)
|
||||
try container.encode(textAlignment, forKey: .textAlignment)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,16 +32,16 @@ import UIKit
|
||||
switch style {
|
||||
case .standard:
|
||||
updateLineConstraints(constant: 1)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mfSilver()
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmCoolGray3
|
||||
case .thin:
|
||||
updateLineConstraints(constant: 1)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack
|
||||
case .medium:
|
||||
updateLineConstraints(constant: 2)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack
|
||||
case .heavy:
|
||||
updateLineConstraints(constant: 4)
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .black
|
||||
backgroundColor = lineModel?.backgroundColor?.uiColor ?? .mvmBlack
|
||||
case .none:
|
||||
updateLineConstraints(constant: 0)
|
||||
}
|
||||
@ -97,6 +97,7 @@ import UIKit
|
||||
}
|
||||
|
||||
extension Line: MVMCoreUIViewConstrainingProtocol {
|
||||
|
||||
open func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -19,101 +19,22 @@ import UIKit
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
/// If true then text textView is currently displaying the stored placeholder text as there is not content to display.
|
||||
public var isShowingPlaceholder: Bool = false {
|
||||
didSet { textViewModel?.showsPlaceholder = isShowingPlaceholder }
|
||||
}
|
||||
public var isShowingPlaceholder: Bool = false
|
||||
|
||||
/// Set to true to hide the blinking textField cursor.
|
||||
public var hideBlinkingCaret = false
|
||||
|
||||
public var textViewModel: TextViewModel? {
|
||||
return model as? TextViewModel
|
||||
}
|
||||
public var placeholder = ""
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
if let color = model.backgroundColor?.uiColor {
|
||||
backgroundColor = color
|
||||
}
|
||||
}
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall
|
||||
public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro
|
||||
|
||||
public var isEnabled: Bool = true {
|
||||
didSet { }
|
||||
}
|
||||
|
||||
/*
|
||||
//--------------------------------------------------
|
||||
// MARK: - Drawing Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
private(set) var fieldState: FieldState = .original {
|
||||
didSet (oldState) {
|
||||
// Will not update if new state is the same as old.
|
||||
if fieldState != oldState {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.fieldState.setStateUI(for: self)
|
||||
}
|
||||
}
|
||||
didSet {
|
||||
isUserInteractionEnabled = isEnabled
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines if the top, left, and right borders should be drawn.
|
||||
private var hideBorders = false
|
||||
|
||||
public var borderStrokeColor: UIColor = .mvmCoolGray3
|
||||
public var bottomStrokeColor: UIColor = .mvmBlack
|
||||
private var borderPath: UIBezierPath = UIBezierPath()
|
||||
private var bottomPath: UIBezierPath = UIBezierPath()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Property Observers
|
||||
//--------------------------------------------------
|
||||
|
||||
private var _isEnabled: Bool = true
|
||||
private var _showError: Bool = false
|
||||
private var _isSelected: Bool = false
|
||||
|
||||
public var isEnabled: Bool {
|
||||
get { return _isEnabled }
|
||||
set (enabled) {
|
||||
|
||||
_isEnabled = enabled
|
||||
_isSelected = false
|
||||
_showError = false
|
||||
|
||||
fieldState = enabled ? .original : .disabled
|
||||
}
|
||||
}
|
||||
|
||||
public var showError: Bool {
|
||||
get { return _showError }
|
||||
set (error) {
|
||||
|
||||
_showError = error
|
||||
_isEnabled = true
|
||||
_isSelected = false
|
||||
|
||||
fieldState = error ? .error : .original
|
||||
}
|
||||
}
|
||||
|
||||
public var isSelected: Bool {
|
||||
get { return _isSelected }
|
||||
set (selected) {
|
||||
|
||||
_isSelected = selected
|
||||
_isEnabled = true
|
||||
|
||||
if _showError {
|
||||
fieldState = selected ? .selectedError : .error
|
||||
} else {
|
||||
fieldState = selected ? .selected : .original
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate
|
||||
//--------------------------------------------------
|
||||
@ -202,7 +123,9 @@ import UIKit
|
||||
smartDashesType = .no
|
||||
smartInsertDeleteType = .no
|
||||
inputAccessoryView = nil
|
||||
// font = textViewModel?.fontStyle.getFont()
|
||||
isAccessibilityElement = true
|
||||
accessibilityTraits = .staticText
|
||||
font = Styler.Font.RegularBodyLarge.getFont()
|
||||
isEditable = true
|
||||
isOpaque = false
|
||||
}
|
||||
@ -210,139 +133,13 @@ import UIKit
|
||||
open func reset() {
|
||||
|
||||
text = ""
|
||||
textAlignment = .left
|
||||
font = Styler.Font.RegularBodyLarge.getFont()
|
||||
inputAccessoryView?.removeFromSuperview()
|
||||
inputAccessoryView = nil
|
||||
initialConfiguration()
|
||||
}
|
||||
|
||||
/*
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
setNeedsDisplay()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw
|
||||
//--------------------------------------------------
|
||||
|
||||
/// This handles the top, left, and right border lines.
|
||||
open override func draw(_ rect: CGRect) {
|
||||
super.draw(rect)
|
||||
|
||||
borderPath.removeAllPoints()
|
||||
bottomPath.removeAllPoints()
|
||||
|
||||
if !hideBorders {
|
||||
// Brings the other half of the line inside the view to prevent line cropping.
|
||||
let origin = bounds.origin
|
||||
let size = frame.size
|
||||
let insetLean: CGFloat = 0.5
|
||||
borderPath.lineWidth = 1
|
||||
|
||||
// Drawing begins and ends from the bottom left.
|
||||
borderPath.move(to: CGPoint(x: origin.x + insetLean, y: origin.y + size.height))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + insetLean))
|
||||
borderPath.addLine(to: CGPoint(x: origin.x + size.width - insetLean, y: origin.y + size.height))
|
||||
|
||||
borderStrokeColor.setStroke()
|
||||
borderPath.stroke()
|
||||
|
||||
let lineWidth: CGFloat = showError || isSelected ? 4 : 1
|
||||
bottomPath.lineWidth = lineWidth
|
||||
bottomPath.move(to: CGPoint(x: origin.x + size.width, y: origin.y + size.height - (lineWidth / 2)))
|
||||
bottomPath.addLine(to: CGPoint(x: origin.x, y: origin.y + size.height - (lineWidth / 2)))
|
||||
|
||||
bottomStrokeColor.setStroke()
|
||||
bottomPath.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Draw States
|
||||
//--------------------------------------------------
|
||||
|
||||
public enum FieldState {
|
||||
case original
|
||||
case error
|
||||
case selectedError
|
||||
case selected
|
||||
case disabled
|
||||
|
||||
public func setStateUI(for inputField: TextView) {
|
||||
|
||||
switch self {
|
||||
case .original:
|
||||
inputField.originalUI()
|
||||
|
||||
case .error:
|
||||
inputField.errorUI()
|
||||
|
||||
case .selectedError:
|
||||
inputField.selectedErrorUI()
|
||||
|
||||
case .selected:
|
||||
inputField.selectedUI()
|
||||
|
||||
case .disabled:
|
||||
inputField.disabledUI()
|
||||
}
|
||||
|
||||
inputField.setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
open func originalUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmCoolGray3
|
||||
bottomStrokeColor = .mvmBlack
|
||||
textColor = isShowingPlaceholder ? textViewModel?.placeholderTextColor.uiColor : textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func errorUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmOrange
|
||||
bottomStrokeColor = .mvmOrange
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func selectedErrorUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmBlack
|
||||
bottomStrokeColor = .mvmOrange
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func selectedUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? true
|
||||
isUserInteractionEnabled = true
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmBlack
|
||||
bottomStrokeColor = .mvmBlack
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
open func disabledUI() {
|
||||
|
||||
isEditable = textViewModel?.editable ?? false
|
||||
isUserInteractionEnabled = false
|
||||
hideBorders = textViewModel?.hideBorders ?? false
|
||||
borderStrokeColor = .mvmCoolGray3
|
||||
bottomStrokeColor = .mvmCoolGray3
|
||||
textColor = textViewModel?.disabledTextColor.uiColor
|
||||
}
|
||||
*/
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
@ -372,7 +169,7 @@ import UIKit
|
||||
|
||||
public func setPlaceholderIfAvailable() {
|
||||
|
||||
if let placeholder = textViewModel?.placeholder, !placeholder.isEmpty && text.isEmpty {
|
||||
if !placeholder.isEmpty && text.isEmpty {
|
||||
setPlaceholderContentTraits()
|
||||
}
|
||||
}
|
||||
@ -381,16 +178,16 @@ import UIKit
|
||||
|
||||
isShowingPlaceholder = false
|
||||
text = ""
|
||||
font = Styler.Font.RegularBodySmall.getFont()//textViewModel?.fontStyle.getFont()
|
||||
textColor = .black//textViewModel?.enabledTextColor.uiColor
|
||||
font = fontStyle.getFont()
|
||||
textColor = .mvmBlack
|
||||
}
|
||||
|
||||
public func setPlaceholderContentTraits() {
|
||||
|
||||
isShowingPlaceholder = true
|
||||
textColor = textViewModel?.placeholderTextColor.uiColor
|
||||
font = textViewModel?.placeholderFontStyle.getFont()
|
||||
text = textViewModel?.placeholder
|
||||
font = placeholderFontStyle.getFont()
|
||||
text = placeholder
|
||||
}
|
||||
|
||||
@objc func dismissFieldInput(_ sender: TextView) {
|
||||
@ -410,7 +207,6 @@ import UIKit
|
||||
@objc public func textViewDidBeginEditing(_ textView: UITextView) {
|
||||
|
||||
setTextAppearance()
|
||||
// isSelected = true
|
||||
proprietorTextDelegate?.textViewDidBeginEditing?(textView)
|
||||
}
|
||||
|
||||
@ -421,7 +217,6 @@ import UIKit
|
||||
|
||||
@objc public func textViewDidChange(_ textView: UITextView) {
|
||||
|
||||
textViewModel?.text = textView.text
|
||||
proprietorTextDelegate?.textViewDidChange?(textView)
|
||||
}
|
||||
|
||||
@ -433,7 +228,6 @@ import UIKit
|
||||
@objc public func textViewDidEndEditing(_ textView: UITextView) {
|
||||
|
||||
setPlaceholderIfAvailable()
|
||||
// isSelected = false
|
||||
proprietorTextDelegate?.textViewDidEndEditing?(textView)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
//
|
||||
// TextViewModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Kevin Christiano on 5/7/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
open class TextViewModel: MoleculeModelProtocol {//, FormFieldProtocol, FormRuleWatcherFieldProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public class var identifier: String {
|
||||
return ""
|
||||
}
|
||||
|
||||
public var baseValue: AnyHashable?
|
||||
public var backgroundColor: Color?
|
||||
// public var fieldKey: String?
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall
|
||||
public var text: String?
|
||||
public var placeholder: String?
|
||||
public var textAlignment: NSTextAlignment = .left
|
||||
// public var groupName: String
|
||||
public var editable: Bool = true
|
||||
public var showsPlaceholder: Bool = false
|
||||
public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3)
|
||||
public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro
|
||||
|
||||
public var isValid: Bool? {
|
||||
didSet { updateUI?() }
|
||||
}
|
||||
|
||||
/// Temporary binding mechanism for the view to update on enable changes.
|
||||
public var updateUI: ActionBlock?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Validation Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
public func formFieldValue() -> AnyHashable? {
|
||||
return text
|
||||
}
|
||||
|
||||
public func setValidity(_ valid: Bool, rule: RulesProtocol) {
|
||||
self.isValid = valid
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case editable
|
||||
// case groupName
|
||||
case textAlignment
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if let editable = try typeContainer.decodeIfPresent(Bool.self, forKey: .editable) {
|
||||
self.editable = editable
|
||||
}
|
||||
|
||||
// if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||
// self.groupName = groupName
|
||||
// }
|
||||
|
||||
if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) {
|
||||
self.textAlignment = textAlignment
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
// try container.encode(groupName, forKey: .groupName)
|
||||
try container.encode(editable, forKey: .editable)
|
||||
try container.encode(textAlignment, forKey: .textAlignment)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user