further textviewfield development
This commit is contained in:
parent
fcca1e3e83
commit
efe3f95746
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
class TextViewEntryField: EntryField {
|
||||
class TextViewEntryField: EntryField, UITextViewDelegate {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -26,12 +26,137 @@ class TextViewEntryField: EntryField {
|
||||
return textView
|
||||
}()
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Computed Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Validate on each entry in the textField. Default: true
|
||||
public var validateEachCharacter: Bool = true
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func dismissFieldInput(_ sender: Any?) {
|
||||
resignFirstResponder()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraint
|
||||
//--------------------------------------------------
|
||||
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Delegate Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
/// The delegate and block for validation. Validates if the text that the user has entered.
|
||||
public weak var observingTextFieldDelegate: ObservingTextFieldDelegate? {
|
||||
didSet {
|
||||
if observingTextFieldDelegate != nil && !observingForChange {
|
||||
observingForChange = true
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(valueChanged), name: UITextView.textDidChangeNotification, object: textView)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(endInputing), name: UITextView.textDidEndEditingNotification, object: textView)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(startEditing), name: UITextView.textDidBeginEditingNotification, object: textView)
|
||||
|
||||
} else if observingTextFieldDelegate == nil && observingForChange {
|
||||
observingForChange = false
|
||||
NotificationCenter.default.removeObserver(self, name: UITextView.textDidChangeNotification, object: textView)
|
||||
NotificationCenter.default.removeObserver(self, name: UITextView.textDidEndEditingNotification, object: textView)
|
||||
NotificationCenter.default.removeObserver(self, name: UITextView.textDidBeginEditingNotification, object: textView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If you're using a ViewController, you must set this to it
|
||||
public weak var uiTextViewDelegate: UITextViewDelegate? {
|
||||
get { return textView.delegate }
|
||||
set { textView.delegate = newValue }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Lifecycle
|
||||
@ -50,13 +175,13 @@ class TextViewEntryField: EntryField {
|
||||
])
|
||||
|
||||
heightConstraint = textView.heightAnchor.constraint(equalToConstant: 0)
|
||||
heightConstraint?.isActive = true
|
||||
|
||||
|
||||
// textView.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||
// textView.addTarget(self, action: #selector(dismissFieldInput), for: .editingDidEnd)
|
||||
//
|
||||
// let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||
// entryFieldContainer.addGestureRecognizer(tap)
|
||||
// textView.addTarget(self, action: #selector(startEditing), for: .editingDidBegin)
|
||||
// textView.addTarget(self, action: #selector(dismissFieldInput), for: .editingDidEnd)
|
||||
//
|
||||
// let tap = UITapGestureRecognizer(target: self, action: #selector(startEditing))
|
||||
// entryFieldContainer.addGestureRecognizer(tap)
|
||||
|
||||
accessibilityElements = [titleLabel, textView, feedbackLabel]
|
||||
}
|
||||
@ -72,6 +197,7 @@ class TextViewEntryField: EntryField {
|
||||
super.reset()
|
||||
|
||||
textView.font = Styler.Font.RegularBodyLarge.getFont()
|
||||
heightConstraint?.constant = 0
|
||||
}
|
||||
|
||||
|
||||
@ -84,18 +210,13 @@ class TextViewEntryField: EntryField {
|
||||
|
||||
guard let model = model as? TextViewEntryFieldModel else { return }
|
||||
|
||||
heightConstraint?.isActive = false
|
||||
if let height = model.height {
|
||||
heightConstraint?.constant = height
|
||||
heightConstraint?.isActive = true
|
||||
}
|
||||
heightConstraint?.constant = model.height ?? 0
|
||||
|
||||
textView.isEditable = model.editable
|
||||
// textView.isEditable = model.editable
|
||||
textView.textAlignment = model.textAlignment
|
||||
textView.textColor = model.enabledTextColor.uiColor
|
||||
// textView.hideBorders = model.hideBorders
|
||||
text = model.text
|
||||
textView.uiTextViewDelegate = delegateObject?.uiTextViewDelegate
|
||||
uiTextViewDelegate = delegateObject?.uiTextViewDelegate
|
||||
|
||||
if let accessibilityText = model.accessibilityText {
|
||||
accessibilityLabel = accessibilityText
|
||||
@ -115,10 +236,10 @@ class TextViewEntryField: EntryField {
|
||||
textView.font = model.fontStyle.getFont()
|
||||
textView.setPlaceholderIfAvailable()
|
||||
|
||||
if isEditable {
|
||||
if textView.isEditable {
|
||||
FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate)
|
||||
let observingDelegate = delegateObject?.uiTextViewDelegate ?? self
|
||||
inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
textView.inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate,
|
||||
action: #selector(textView.dismissFieldInput))
|
||||
|
||||
if (model.selected ?? false) && !model.wasInitiallySelected {
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
@ -19,14 +20,11 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
|
||||
public var accessibilityText: String?
|
||||
public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall
|
||||
public var textAlignment: NSTextAlignment = .left
|
||||
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 showsPlaceholder: Bool = false
|
||||
public var hideBorders: Bool = false
|
||||
public var editable: Bool = true
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
@ -37,7 +35,6 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
case fontStyle
|
||||
case textAlignment
|
||||
case height
|
||||
case hideBorders
|
||||
case placeholderFontStyle
|
||||
case placeholderTextColor
|
||||
case editable
|
||||
@ -63,14 +60,6 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
self.textAlignment = textAlignment
|
||||
}
|
||||
|
||||
if let hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) {
|
||||
self.hideBorders = hideBorders
|
||||
}
|
||||
|
||||
if let editable = try typeContainer.decodeIfPresent(Bool.self, forKey: .editable) {
|
||||
self.editable = editable
|
||||
}
|
||||
|
||||
if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) {
|
||||
self.fontStyle = fontStyle
|
||||
}
|
||||
@ -85,11 +74,10 @@ class TextViewEntryFieldModel: TextEntryFieldModel {
|
||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||
try container.encodeIfPresent(height, forKey: .height)
|
||||
try container.encode(fontStyle, forKey: .fontStyle)
|
||||
try container.encode(hideBorders, forKey: .hideBorders)
|
||||
try container.encode(text, forKey: .text)
|
||||
try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle)
|
||||
try container.encode(placeholderTextColor, forKey: .placeholderTextColor)
|
||||
try container.encode(textAlignment, forKey: .textAlignment)
|
||||
try container.encode(editable, forKey: .editable)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ import Foundation
|
||||
try? ModelRegistry.register(LabelAttributeActionModel.self)
|
||||
|
||||
// TextView
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: TextView.self, viewModelClass: TextViewModel.self)
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: TextViewEntryField.self, viewModelClass: TextViewEntryFieldModel.self)
|
||||
|
||||
// Buttons
|
||||
MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self)
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import UIKit
|
||||
|
||||
|
||||
@objc open class TextView: UITextView, UITextViewDelegate, MVMCoreViewProtocol {
|
||||
@objc open class TextView: UITextView, UITextViewDelegate, MVMCoreViewProtocol, MoleculeViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -26,9 +26,21 @@ import UIKit
|
||||
/// Set to true to hide the blinking textField cursor.
|
||||
public var hideBlinkingCaret = false
|
||||
|
||||
public var textViewEntryFieldModel: TextViewEntryFieldModel? {
|
||||
return model as? TextViewEntryFieldModel
|
||||
public var textViewModel: TextViewModel? {
|
||||
return model as? TextViewModel
|
||||
}
|
||||
|
||||
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
if let color = model.backgroundColor?.uiColor {
|
||||
backgroundColor = color
|
||||
}
|
||||
}
|
||||
|
||||
public var isEnabled: Bool = true {
|
||||
didSet { }
|
||||
}
|
||||
|
||||
/*
|
||||
//--------------------------------------------------
|
||||
// MARK: - Drawing Properties
|
||||
@ -202,6 +214,7 @@ import UIKit
|
||||
inputAccessoryView = nil
|
||||
initialConfiguration()
|
||||
}
|
||||
|
||||
/*
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
@ -368,8 +381,8 @@ import UIKit
|
||||
|
||||
isShowingPlaceholder = false
|
||||
text = ""
|
||||
font = textViewModel?.fontStyle.getFont()
|
||||
textColor = textViewModel?.enabledTextColor.uiColor
|
||||
font = Styler.Font.RegularBodySmall.getFont()//textViewModel?.fontStyle.getFont()
|
||||
textColor = .black//textViewModel?.enabledTextColor.uiColor
|
||||
}
|
||||
|
||||
public func setPlaceholderContentTraits() {
|
||||
@ -397,7 +410,7 @@ import UIKit
|
||||
@objc public func textViewDidBeginEditing(_ textView: UITextView) {
|
||||
|
||||
setTextAppearance()
|
||||
isSelected = true
|
||||
// isSelected = true
|
||||
proprietorTextDelegate?.textViewDidBeginEditing?(textView)
|
||||
}
|
||||
|
||||
@ -420,7 +433,7 @@ import UIKit
|
||||
@objc public func textViewDidEndEditing(_ textView: UITextView) {
|
||||
|
||||
setPlaceholderIfAvailable()
|
||||
isSelected = false
|
||||
// isSelected = false
|
||||
proprietorTextDelegate?.textViewDidEndEditing?(textView)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,4 +6,87 @@
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
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