From daa37c5addee1ebd46b2cf92fc5a0e3c075f8c60 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 3 Apr 2020 10:46:32 -0400 Subject: [PATCH 01/25] textview stuff --- MVMCoreUI.xcodeproj/project.pbxproj | 8 ++++++++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 +++ 2 files changed, 11 insertions(+) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 60829e96..d2894810 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -87,6 +87,8 @@ 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; 0A6682A22434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */; }; 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */; }; + 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; }; + 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */; }; 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; @@ -474,6 +476,8 @@ 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyText.swift; sourceTree = ""; }; 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyTextModel.swift; sourceTree = ""; }; + 0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; + 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewModel.swift; sourceTree = ""; }; 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = ""; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; @@ -1709,6 +1713,8 @@ D2B18B7D236090D500A9AEDC /* BaseClasses */ = { isa = PBXGroup; children = ( + 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */, + 0A6682B3243769C700AD3CA1 /* TextView.swift */, C003506023AA94CD00B6AC29 /* Button.swift */, D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, @@ -1929,6 +1935,7 @@ 017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, D27CD40E2322EEAF00C1DC07 /* TabsTableViewCell.swift in Sources */, + 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */, D224799B231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift in Sources */, 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */, D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, @@ -2095,6 +2102,7 @@ D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */, 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, + 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */, 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */, 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 7f56f142..90e4d62d 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -52,6 +52,9 @@ import Foundation try? ModelRegistry.register(LabelAttributeStrikeThroughModel.self) try? ModelRegistry.register(LabelAttributeActionModel.self) + // TextView + MoleculeObjectMapping.shared()?.register(viewClass: TextView.self, viewModelClass: TextViewModel.self) + // Buttons MoleculeObjectMapping.shared()?.register(viewClass: PillButton.self, viewModelClass: ButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: TwoButtonView.self, viewModelClass: TwoButtonViewModel.self) From 174d26edc424129bf5e1a5c7f20395c7aadc8f01 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 3 Apr 2020 10:59:38 -0400 Subject: [PATCH 02/25] textview --- MVMCoreUI/BaseClasses/TextView.swift | 275 ++++++++++++++++++++++ MVMCoreUI/BaseClasses/TextViewModel.swift | 90 +++++++ 2 files changed, 365 insertions(+) create mode 100644 MVMCoreUI/BaseClasses/TextView.swift create mode 100644 MVMCoreUI/BaseClasses/TextViewModel.swift diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift new file mode 100644 index 00000000..547de4a2 --- /dev/null +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -0,0 +1,275 @@ +// +// TextView.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 4/1/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + + +@objc protocol MFTextViewDelegate { + // Dismisses the keyboard. + @objc optional func dismissFieldInput(_ sender: Any?) +} + + +@objc open class TextView: UITextView, UITextViewDelegate { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open var model: MoleculeModelProtocol? + + private var initialSetupPerformed = false + + /// Set to true to hide the blinking textField cursor. + public var hideBlinkingCaret = false + + public var hideBorder = true + + public var borderPath: UIBezierPath? + + public var errorShowing = false + + weak var bottomLine: SeparatorView? + + public var placeholderFont: UIFont = MFStyler.fontB3()! { + didSet { + if text.isEmpty { + font = placeholderFont + } + } + } + + public var placeholder: String = "" { + didSet { + if text.isEmpty { + text = placeholder + } + } + } + + public var placeholderTextColor: UIColor = .mvmCoolGray3 + + public var displaysPlaceholder = false + + private(set) var textStore: String = "" + + public override var text: String! { + didSet { + if displaysPlaceholder && text.isEmpty { + text = placeholder + textColor = placeholderTextColor + } else { + textColor = .mvmBlack + } + } + } + + private(set) var textFont: UIFont = MFStyler.fontB2()! + + public override var font: UIFont? { + didSet { + if displaysPlaceholder && text.isEmpty { + font = placeholderFont + } else { + textColor = .mvmBlack + } + } + } + + //-------------------------------------------------- + // MARK: - Delegate + //-------------------------------------------------- + + /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. + public weak var didDeleteDelegate: TextFieldDidDeleteProtocol? + + /// If you're using a MFViewController, you must set this to it + public weak var uiTextViewDelegate: UITextViewDelegate? { + get { return delegate } + set { delegate = newValue } + } + + //-------------------------------------------------- + // MARK: - Constraint + //-------------------------------------------------- + + public var heightConstraint: NSLayoutConstraint? + + //-------------------------------------------------- + // MARK: - Initialization + //-------------------------------------------------- + + public override init(frame: CGRect, textContainer: NSTextContainer?) { + super.init(frame: .zero, textContainer: nil) + initialSetup() + } + + public convenience init() { + self.init(frame: .zero, textContainer: nil) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + + convenience init(placeholderText: String, delegate: UITextViewDelegate?) { + self.init(frame: .zero, textContainer: nil) + self.delegate = delegate + displaysPlaceholder = true + self.placeholder = placeholderText + } + + public func initialSetup() { + + if !initialSetupPerformed { + tintColor = .black + initialSetupPerformed = true + setupView() + } + } + + open override func caretRect(for position: UITextPosition) -> CGRect { + + if hideBlinkingCaret { + return .zero + } + + let caretRect = super.caretRect(for: position) + return CGRect(origin: caretRect.origin, size: CGSize(width: 1, height: caretRect.height)) + } + + open override func deleteBackward() { + super.deleteBackward() + didDeleteDelegate?.textFieldDidDelete() + } + + //-------------------------------------------------- + // MARK: - Drawing + //-------------------------------------------------- + + open override func draw(_ rect: CGRect) { + super.draw(rect) + + borderPath?.removeAllPoints() + + if !hideBorder { + layer.cornerRadius = 0 + borderPath = UIBezierPath() + let width = frame.origin.x + frame.size.width + let height = frame.origin.y + frame.size.height + + borderPath?.move(to: CGPoint(x: frame.origin.x, y: height)) + borderPath?.addLine(to: CGPoint(x: frame.origin.x, y: frame.origin.y)) + borderPath?.addLine(to: CGPoint(x: width, y: frame.origin.y)) + borderPath?.addLine(to: CGPoint(x: width, y: height)) + borderPath?.lineWidth = 1 + + var strokeColor: UIColor? + + if errorShowing { + strokeColor = .mvmOrangeAA + bottomLine?.backgroundColor = .mvmOrangeAA + } else { + strokeColor = .mvmCoolGray3 + bottomLine?.backgroundColor = .mvmBlack + } + strokeColor?.setStroke() + borderPath?.stroke() + } + } + + //-------------------------------------------------- + // MARK: - Observing Methods + //-------------------------------------------------- + + /// Executes on UITextView.textDidEndEditingNotification + @objc open func dismissFieldInput() { + resignFirstResponder() + } + + //#pragma Mark UITextView Delegate methods forwarding + @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { + + return delegate?.textViewShouldBeginEditing?(textView) ?? true + } + + @objc public func textViewDidBeginEditing(_ textView: UITextView) { + + delegate?.textViewDidBeginEditing?(textView) + } + + @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + + return delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true + } + + @objc public func textViewDidChange(_ textView: UITextView) { + + delegate?.textViewDidChange?(textView) + } + + @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool { + return delegate?.textViewShouldEndEditing?(textView) ?? true + } + + @objc public func textViewDidEndEditing(_ textView: UITextView) { + + delegate?.textViewDidEndEditing?(textView) + } +} + +/// MARK:- MVMCoreViewProtocol +extension TextView: MVMCoreViewProtocol { + + open func updateView(_ size: CGFloat) { } + + /// Will be called only once. + open func setupView() { + translatesAutoresizingMaskIntoConstraints = false + insetsLayoutMarginsFromSafeArea = false + clipsToBounds = true + errorShowing = false + hideBorder = false + layer.cornerRadius = CGFloat(CornerRadiusLarge) + // Disable SmartQuotes + smartQuotesType = .no + smartDashesType = .no + smartInsertDeleteType = .no + font = textFont + MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegate) + textContainerInset = UIEdgeInsets(top: PaddingTwo, left: PaddingTwo, bottom: PaddingTwo, right: PaddingOne) + } +} + +/// MARK:- MoleculeViewProtocol +extension TextView: MoleculeViewProtocol { + + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + self.model = model + + if let color = model.backgroundColor?.uiColor { + backgroundColor = color + } + + guard let model = model as? TextViewModel else { return } + + if let height = model.height { + heightConstraint = heightAnchor.constraint(equalToConstant: height) + heightConstraint?.isActive = true + } + + text = model.text + placeholder = model.placeholder ?? "" + MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegate) + } + + open func reset() { + backgroundColor = .clear + text = "" + } +} diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift new file mode 100644 index 00000000..655b6933 --- /dev/null +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -0,0 +1,90 @@ +// +// TextViewModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 4/2/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +open class TextViewModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public static var identifier: String = "textView" + public var backgroundColor: Color? + public var text: String = "" + public var accessibilityText: String? + public var textColor: Color? + public var fontStyle: LabelModel.FontStyle? + public var textAlignment: NSTextAlignment? + public var height: CGFloat? + public var placeholder: String? + public var isEditable: Bool = true + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case moleculeName + case text + case accessibilityText + case textColor + case backgroundColor + case fontStyle + case fontName + case fontSize + case textAlignment + case attributes + case height + case placeholder + case isEditable + } + + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + + public init(text: String) { + self.text = text + } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let text = try typeContainer.decodeIfPresent(String.self, forKey: .text) { + self.text = text + } + placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .text) + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) + textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) + height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) + + if let isEditable = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEditable) { + self.isEditable = isEditable + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(moleculeName, forKey: .moleculeName) + try container.encode(text, forKey: .text) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) + try container.encodeIfPresent(textColor, forKey: .textColor) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(fontStyle, forKey: .fontStyle) + try container.encodeIfPresent(textAlignment, forKey: .textAlignment) + try container.encodeIfPresent(height, forKey: .height) + try container.encodeIfPresent(isEditable, forKey: .isEditable) + } +} From 3f69b19a0556f0b8f0b02b326e5e8372e9507178 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 3 Apr 2020 13:29:11 -0400 Subject: [PATCH 03/25] small change --- MVMCoreUI/BaseClasses/TextView.swift | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 547de4a2..23117718 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -27,11 +27,13 @@ import UIKit /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false + /// Hides the custom drawn border. public var hideBorder = true - public var borderPath: UIBezierPath? + private var borderPath: UIBezierPath? - public var errorShowing = false + /// If true + public var hasError = false weak var bottomLine: SeparatorView? @@ -171,7 +173,7 @@ import UIKit var strokeColor: UIColor? - if errorShowing { + if hasError { strokeColor = .mvmOrangeAA bottomLine?.backgroundColor = .mvmOrangeAA } else { @@ -233,7 +235,7 @@ extension TextView: MVMCoreViewProtocol { translatesAutoresizingMaskIntoConstraints = false insetsLayoutMarginsFromSafeArea = false clipsToBounds = true - errorShowing = false + hasError = false hideBorder = false layer.cornerRadius = CGFloat(CornerRadiusLarge) // Disable SmartQuotes From 8141fa934f2e0dee8473616fcd10b95dbd9dc2aa Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 8 Apr 2020 13:53:53 -0400 Subject: [PATCH 04/25] latest textview --- .../Atoms/TextFields/TextEntryField.swift | 2 +- .../TextFields/TextEntryFieldModel.swift | 1 + MVMCoreUI/BaseClasses/TextView.swift | 79 +++++-------------- MVMCoreUI/BaseClasses/TextViewModel.swift | 46 +++++++---- .../MVMCoreUIDelegateObject.swift | 5 +- 5 files changed, 57 insertions(+), 76 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift index 2e7df5ee..564f669b 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryField.swift @@ -129,7 +129,7 @@ import UIKit } } - /// If you're using a MFViewController, you must set this to it + /// If you're using a ViewController, you must set this to it public weak var uiTextFieldDelegate: UITextFieldDelegate? { get { return textField.delegate } set { textField.delegate = newValue } diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index c35d812e..761fa5b2 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -13,6 +13,7 @@ case password case number case email + case text } //-------------------------------------------------- diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 23117718..ff18128f 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -9,12 +9,6 @@ import UIKit -@objc protocol MFTextViewDelegate { - // Dismisses the keyboard. - @objc optional func dismissFieldInput(_ sender: Any?) -} - - @objc open class TextView: UITextView, UITextViewDelegate { //-------------------------------------------------- // MARK: - Properties @@ -27,17 +21,9 @@ import UIKit /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false - /// Hides the custom drawn border. - public var hideBorder = true - - private var borderPath: UIBezierPath? - - /// If true - public var hasError = false - weak var bottomLine: SeparatorView? - public var placeholderFont: UIFont = MFStyler.fontB3()! { + public var placeholderFont: UIFont = MFStyler.fontRegularMicro() { didSet { if text.isEmpty { font = placeholderFont @@ -89,7 +75,7 @@ import UIKit /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. public weak var didDeleteDelegate: TextFieldDidDeleteProtocol? - /// If you're using a MFViewController, you must set this to it + /// If you're using a ViewController, you must set this to it public weak var uiTextViewDelegate: UITextViewDelegate? { get { return delegate } set { delegate = newValue } @@ -129,7 +115,7 @@ import UIKit public func initialSetup() { if !initialSetupPerformed { - tintColor = .black + tintColor = .mvmBlack initialSetupPerformed = true setupView() } @@ -150,47 +136,13 @@ import UIKit didDeleteDelegate?.textFieldDidDelete() } - //-------------------------------------------------- - // MARK: - Drawing - //-------------------------------------------------- - - open override func draw(_ rect: CGRect) { - super.draw(rect) - - borderPath?.removeAllPoints() - - if !hideBorder { - layer.cornerRadius = 0 - borderPath = UIBezierPath() - let width = frame.origin.x + frame.size.width - let height = frame.origin.y + frame.size.height - - borderPath?.move(to: CGPoint(x: frame.origin.x, y: height)) - borderPath?.addLine(to: CGPoint(x: frame.origin.x, y: frame.origin.y)) - borderPath?.addLine(to: CGPoint(x: width, y: frame.origin.y)) - borderPath?.addLine(to: CGPoint(x: width, y: height)) - borderPath?.lineWidth = 1 - - var strokeColor: UIColor? - - if hasError { - strokeColor = .mvmOrangeAA - bottomLine?.backgroundColor = .mvmOrangeAA - } else { - strokeColor = .mvmCoolGray3 - bottomLine?.backgroundColor = .mvmBlack - } - strokeColor?.setStroke() - borderPath?.stroke() - } - } - //-------------------------------------------------- // MARK: - Observing Methods //-------------------------------------------------- /// Executes on UITextView.textDidEndEditingNotification @objc open func dismissFieldInput() { + resignFirstResponder() } @@ -216,6 +168,7 @@ import UIKit } @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool { + return delegate?.textViewShouldEndEditing?(textView) ?? true } @@ -232,19 +185,19 @@ extension TextView: MVMCoreViewProtocol { /// Will be called only once. open func setupView() { + translatesAutoresizingMaskIntoConstraints = false insetsLayoutMarginsFromSafeArea = false + showsVerticalScrollIndicator = false + showsHorizontalScrollIndicator = false clipsToBounds = true - hasError = false - hideBorder = false - layer.cornerRadius = CGFloat(CornerRadiusLarge) - // Disable SmartQuotes smartQuotesType = .no smartDashesType = .no smartInsertDeleteType = .no font = textFont - MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegate) - textContainerInset = UIEdgeInsets(top: PaddingTwo, left: PaddingTwo, bottom: PaddingTwo, right: PaddingOne) + layer.borderWidth = 1 + layer.borderColor = UIColor.mvmBlack.cgColor + isEditable = true } } @@ -265,12 +218,18 @@ extension TextView: MoleculeViewProtocol { heightConstraint?.isActive = true } + isEditable = model.isEditable + textAlignment = model.textAlignment + textColor = model.textColor.uiColor text = model.text - placeholder = model.placeholder ?? "" - MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegate) + placeholder = model.placeholder + uiTextViewDelegate = delegateObject?.uiTextViewDelegate + MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) } open func reset() { + + setNeedsDisplay() backgroundColor = .clear text = "" } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 655b6933..1f7f70a7 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -18,11 +18,12 @@ open class TextViewModel: MoleculeModelProtocol { public var backgroundColor: Color? public var text: String = "" public var accessibilityText: String? - public var textColor: Color? + public var textColor: Color = Color(uiColor: .mvmBlack) public var fontStyle: LabelModel.FontStyle? - public var textAlignment: NSTextAlignment? + public var textAlignment: NSTextAlignment = .left public var height: CGFloat? - public var placeholder: String? + public var placeholder: String = "" + public var placeholderFont: LabelModel.FontStyle = LabelModel.FontStyle.RegularMicro public var isEditable: Bool = true //-------------------------------------------------- @@ -36,12 +37,11 @@ open class TextViewModel: MoleculeModelProtocol { case textColor case backgroundColor case fontStyle - case fontName - case fontSize case textAlignment case attributes case height case placeholder + case placeholderFont case isEditable } @@ -59,32 +59,50 @@ open class TextViewModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let text = try typeContainer.decodeIfPresent(String.self, forKey: .text) { self.text = text } - placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .text) - accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) - textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) - textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) - height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) + + if let placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) { + self.placeholder = placeholder + } + + if let placeholderFont = try typeContainer.decodeIfPresent(String.self, forKey: .placeholderFont), + let font = LabelModel.FontStyle(rawValue: placeholderFont) { + self.placeholderFont = font + } + + if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { + self.textAlignment = textAlignment + } + + if let textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) { + self.textColor = textColor + } if let isEditable = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEditable) { self.isEditable = isEditable } + + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) + height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encode(text, forKey: .text) + try container.encode(placeholder, forKey: .placeholder) + try container.encode(placeholderFont, forKey: .placeholderFont) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) - try container.encodeIfPresent(textAlignment, forKey: .textAlignment) + try container.encode(textAlignment, forKey: .textAlignment) try container.encodeIfPresent(height, forKey: .height) - try container.encodeIfPresent(isEditable, forKey: .isEditable) + try container.encode(isEditable, forKey: .isEditable) } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift index c9d5d34c..c63c4a87 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift @@ -8,10 +8,13 @@ import UIKit + open class MVMCoreUIDelegateObject: DelegateObject { + public weak var formHolderDelegate: FormHolderProtocol? public weak var buttonDelegate: ButtonDelegateProtocol? public weak var uiTextFieldDelegate: UITextFieldDelegate? + public weak var uiTextViewDelegate: UITextViewDelegate? public weak var observingTextFieldDelegate: ObservingTextFieldDelegate? public weak var moleculeDelegate: MoleculeDelegateProtocol? @@ -20,6 +23,7 @@ open class MVMCoreUIDelegateObject: DelegateObject { formHolderDelegate = delegate as? FormHolderProtocol buttonDelegate = delegate as? ButtonDelegateProtocol uiTextFieldDelegate = delegate as? UITextFieldDelegate + uiTextViewDelegate = delegate as? UITextViewDelegate observingTextFieldDelegate = delegate as? ObservingTextFieldDelegate moleculeDelegate = delegate as? MoleculeDelegateProtocol } @@ -28,4 +32,3 @@ open class MVMCoreUIDelegateObject: DelegateObject { return controller?.delegateObject?() as? MVMCoreUIDelegateObject } } - From 6e96be982bec2d00b53d8c65867183e25e776b63 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 8 Apr 2020 16:21:46 -0400 Subject: [PATCH 05/25] current textview state --- MVMCoreUI/BaseClasses/TextView.swift | 76 ++++++++++++++--------- MVMCoreUI/BaseClasses/TextViewModel.swift | 37 ++++++++--- 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index ff18128f..6e80b623 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -21,7 +21,8 @@ import UIKit /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false - weak var bottomLine: SeparatorView? + private var textTraits: (color: UIColor, font: UIFont) = (color: .mvmBlack, font: MFStyler.fontRegularBodySmall()) + private var placeholderTraits: (color: UIColor, font: UIFont) = (color: .mvmCoolGray3, font: MFStyler.fontRegularMicro() ) public var placeholderFont: UIFont = MFStyler.fontRegularMicro() { didSet { @@ -41,32 +42,19 @@ import UIKit public var placeholderTextColor: UIColor = .mvmCoolGray3 - public var displaysPlaceholder = false + public var showsPlaceholder = true - private(set) var textStore: String = "" - - public override var text: String! { + public var isShowingPlaceholder = true { didSet { - if displaysPlaceholder && text.isEmpty { + textColor = isShowingPlaceholder ? placeholderTextColor : .mvmBlack + font = isShowingPlaceholder ? placeholderFont : textFont + if isShowingPlaceholder { text = placeholder - textColor = placeholderTextColor - } else { - textColor = .mvmBlack } } } - private(set) var textFont: UIFont = MFStyler.fontB2()! - - public override var font: UIFont? { - didSet { - if displaysPlaceholder && text.isEmpty { - font = placeholderFont - } else { - textColor = .mvmBlack - } - } - } + private(set) var textFont: UIFont = MFStyler.fontRegularBodySmall() //-------------------------------------------------- // MARK: - Delegate @@ -75,10 +63,16 @@ import UIKit /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. public weak var didDeleteDelegate: TextFieldDidDeleteProtocol? + /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. + private weak var proprietorTextDelegate: UITextViewDelegate? + /// If you're using a ViewController, you must set this to it public weak var uiTextViewDelegate: UITextViewDelegate? { get { return delegate } - set { delegate = newValue } + set { + delegate = self + proprietorTextDelegate = newValue + } } //-------------------------------------------------- @@ -108,7 +102,7 @@ import UIKit convenience init(placeholderText: String, delegate: UITextViewDelegate?) { self.init(frame: .zero, textContainer: nil) self.delegate = delegate - displaysPlaceholder = true + showsPlaceholder = true self.placeholder = placeholderText } @@ -134,10 +128,17 @@ import UIKit open override func deleteBackward() { super.deleteBackward() didDeleteDelegate?.textFieldDidDelete() + + if isShowingPlaceholder { + text = "" + isShowingPlaceholder = false + } else if text.isEmpty { + isShowingPlaceholder = true + } } //-------------------------------------------------- - // MARK: - Observing Methods + // MARK: - UITextViewDelegate //-------------------------------------------------- /// Executes on UITextView.textDidEndEditingNotification @@ -149,32 +150,32 @@ import UIKit //#pragma Mark UITextView Delegate methods forwarding @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { - return delegate?.textViewShouldBeginEditing?(textView) ?? true + return proprietorTextDelegate?.textViewShouldBeginEditing?(textView) ?? true } @objc public func textViewDidBeginEditing(_ textView: UITextView) { - delegate?.textViewDidBeginEditing?(textView) + proprietorTextDelegate?.textViewDidBeginEditing?(textView) } @objc public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - return delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true + return proprietorTextDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true } @objc public func textViewDidChange(_ textView: UITextView) { - delegate?.textViewDidChange?(textView) + proprietorTextDelegate?.textViewDidChange?(textView) } @objc public func textViewShouldEndEditing(_ textView: UITextView) -> Bool { - return delegate?.textViewShouldEndEditing?(textView) ?? true + return proprietorTextDelegate?.textViewShouldEndEditing?(textView) ?? true } @objc public func textViewDidEndEditing(_ textView: UITextView) { - delegate?.textViewDidEndEditing?(textView) + proprietorTextDelegate?.textViewDidEndEditing?(textView) } } @@ -190,6 +191,7 @@ extension TextView: MVMCoreViewProtocol { insetsLayoutMarginsFromSafeArea = false showsVerticalScrollIndicator = false showsHorizontalScrollIndicator = false + backgroundColor = .clear clipsToBounds = true smartQuotesType = .no smartDashesType = .no @@ -221,10 +223,24 @@ extension TextView: MoleculeViewProtocol { isEditable = model.isEditable textAlignment = model.textAlignment textColor = model.textColor.uiColor + layer.borderColor = model.borderColor?.cgColor + layer.borderWidth = model.borderWidth + +// font = model.fontStyle + text = model.text + isShowingPlaceholder = model.text.isEmpty placeholder = model.placeholder + // placeholderFont = model.placeholderFont uiTextViewDelegate = delegateObject?.uiTextViewDelegate - MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) + + if let accessibilityText = model.accessibilityText { + accessibilityLabel = accessibilityText + } + + if isEditable { + MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) + } } open func reset() { diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 1f7f70a7..6b335614 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -19,12 +19,17 @@ open class TextViewModel: MoleculeModelProtocol { public var text: String = "" public var accessibilityText: String? public var textColor: Color = Color(uiColor: .mvmBlack) + public var fontSize: CGFloat? + public var fontName: String? public var fontStyle: LabelModel.FontStyle? public var textAlignment: NSTextAlignment = .left public var height: CGFloat? public var placeholder: String = "" public var placeholderFont: LabelModel.FontStyle = LabelModel.FontStyle.RegularMicro public var isEditable: Bool = true + public var borderColor: Color? + public var borderWidth: CGFloat = 0 + public var showsPlaceholder: Bool = true //-------------------------------------------------- // MARK: - Keys @@ -32,14 +37,18 @@ open class TextViewModel: MoleculeModelProtocol { private enum CodingKeys: String, CodingKey { case moleculeName + case backgroundColor case text case accessibilityText case textColor - case backgroundColor case fontStyle + case fontSize + case fontName case textAlignment case attributes case height + case borderColor + case borderWidth case placeholder case placeholderFont case isEditable @@ -68,9 +77,8 @@ open class TextViewModel: MoleculeModelProtocol { self.placeholder = placeholder } - if let placeholderFont = try typeContainer.decodeIfPresent(String.self, forKey: .placeholderFont), - let font = LabelModel.FontStyle(rawValue: placeholderFont) { - self.placeholderFont = font + if let placeholderFont = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .placeholderFont) { + self.placeholderFont = placeholderFont } if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { @@ -85,8 +93,15 @@ open class TextViewModel: MoleculeModelProtocol { self.isEditable = isEditable } + if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { + self.borderWidth = borderWidth + } + + borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .accessibilityText) + fontName = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } @@ -94,15 +109,19 @@ open class TextViewModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) + try container.encodeIfPresent(textColor, forKey: .textColor) + try container.encodeIfPresent(fontStyle, forKey: .fontStyle) + try container.encodeIfPresent(height, forKey: .height) + try container.encodeIfPresent(borderColor, forKey: .borderColor) + try container.encodeIfPresent(fontSize, forKey: .fontSize) + try container.encodeIfPresent(fontName, forKey: .fontName) try container.encode(text, forKey: .text) try container.encode(placeholder, forKey: .placeholder) try container.encode(placeholderFont, forKey: .placeholderFont) - try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) - try container.encodeIfPresent(textColor, forKey: .textColor) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) - try container.encodeIfPresent(fontStyle, forKey: .fontStyle) try container.encode(textAlignment, forKey: .textAlignment) - try container.encodeIfPresent(height, forKey: .height) try container.encode(isEditable, forKey: .isEditable) + try container.encode(borderWidth, forKey: .borderWidth) } } From 01ef563f70190296cc171e8be900b7ca43063d14 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 9 Apr 2020 08:12:49 -0400 Subject: [PATCH 06/25] txtv --- MVMCoreUI/BaseClasses/TextView.swift | 64 ++++++++-------------------- 1 file changed, 18 insertions(+), 46 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 6e80b623..bc1c2133 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -18,43 +18,13 @@ import UIKit private var initialSetupPerformed = false + public var isShowingPlaceholder = true + /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false private var textTraits: (color: UIColor, font: UIFont) = (color: .mvmBlack, font: MFStyler.fontRegularBodySmall()) - private var placeholderTraits: (color: UIColor, font: UIFont) = (color: .mvmCoolGray3, font: MFStyler.fontRegularMicro() ) - - public var placeholderFont: UIFont = MFStyler.fontRegularMicro() { - didSet { - if text.isEmpty { - font = placeholderFont - } - } - } - - public var placeholder: String = "" { - didSet { - if text.isEmpty { - text = placeholder - } - } - } - - public var placeholderTextColor: UIColor = .mvmCoolGray3 - - public var showsPlaceholder = true - - public var isShowingPlaceholder = true { - didSet { - textColor = isShowingPlaceholder ? placeholderTextColor : .mvmBlack - font = isShowingPlaceholder ? placeholderFont : textFont - if isShowingPlaceholder { - text = placeholder - } - } - } - - private(set) var textFont: UIFont = MFStyler.fontRegularBodySmall() + private var placeholderTraits: (text: String, color: UIColor, font: UIFont) = (text: "", color: .mvmCoolGray3, font: MFStyler.fontRegularMicro() ) //-------------------------------------------------- // MARK: - Delegate @@ -102,8 +72,7 @@ import UIKit convenience init(placeholderText: String, delegate: UITextViewDelegate?) { self.init(frame: .zero, textContainer: nil) self.delegate = delegate - showsPlaceholder = true - self.placeholder = placeholderText + self.placeholderTraits.text = placeholderText } public func initialSetup() { @@ -128,12 +97,20 @@ import UIKit open override func deleteBackward() { super.deleteBackward() didDeleteDelegate?.textFieldDidDelete() + } + + open func setTextViewState() { if isShowingPlaceholder { text = "" + font = textTraits.font + textColor = textTraits.color isShowingPlaceholder = false } else if text.isEmpty { isShowingPlaceholder = true + textColor = placeholderTraits.color + text = placeholderTraits.text + font = placeholderTraits.font } } @@ -141,12 +118,6 @@ import UIKit // MARK: - UITextViewDelegate //-------------------------------------------------- - /// Executes on UITextView.textDidEndEditingNotification - @objc open func dismissFieldInput() { - - resignFirstResponder() - } - //#pragma Mark UITextView Delegate methods forwarding @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { @@ -165,6 +136,8 @@ import UIKit @objc public func textViewDidChange(_ textView: UITextView) { + setTextViewState() + proprietorTextDelegate?.textViewDidChange?(textView) } @@ -196,7 +169,7 @@ extension TextView: MVMCoreViewProtocol { smartQuotesType = .no smartDashesType = .no smartInsertDeleteType = .no - font = textFont + font = textTraits.font layer.borderWidth = 1 layer.borderColor = UIColor.mvmBlack.cgColor isEditable = true @@ -225,13 +198,12 @@ extension TextView: MoleculeViewProtocol { textColor = model.textColor.uiColor layer.borderColor = model.borderColor?.cgColor layer.borderWidth = model.borderWidth - // font = model.fontStyle - + // placeholderFont = model.placeholderFont text = model.text isShowingPlaceholder = model.text.isEmpty - placeholder = model.placeholder - // placeholderFont = model.placeholderFont + placeholderTraits.text = model.placeholder + uiTextViewDelegate = delegateObject?.uiTextViewDelegate if let accessibilityText = model.accessibilityText { From 76fe9749ad7bb59b2d4331c6da183d37a1fc585c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 9 Apr 2020 10:05:48 -0400 Subject: [PATCH 07/25] latest --- MVMCoreUI/BaseClasses/TextView.swift | 25 ++++++++++++++++++++--- MVMCoreUI/BaseClasses/TextViewModel.swift | 4 ++-- MVMCoreUI/Styles/MFStyler.h | 1 + MVMCoreUI/Styles/MFStyler.m | 22 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index bc1c2133..735abfaf 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -18,6 +18,9 @@ import UIKit private var initialSetupPerformed = false + /// Set this property if you want updateView to update the font based on this standard and the size passed in. + public var standardFontSize: CGFloat = 0.0 + public var isShowingPlaceholder = true /// Set to true to hide the blinking textField cursor. @@ -198,18 +201,34 @@ extension TextView: MoleculeViewProtocol { textColor = model.textColor.uiColor layer.borderColor = model.borderColor?.cgColor layer.borderWidth = model.borderWidth -// font = model.fontStyle - // placeholderFont = model.placeholderFont +// placeholderFont = model.placeholderFont text = model.text isShowingPlaceholder = model.text.isEmpty placeholderTraits.text = model.placeholder - uiTextViewDelegate = delegateObject?.uiTextViewDelegate if let accessibilityText = model.accessibilityText { accessibilityLabel = accessibilityText } + if let fontStyle = model.fontStyle?.rawValue { + MFStyler.styleTextView(self, withStyle: fontStyle, genericScaling: false) + standardFontSize = font?.pointSize ?? 0 + if let font = font { + textTraits.font = font + } + } else { + let fontSize = model.fontSize + if let fontSize = fontSize { + standardFontSize = fontSize + } + if let fontName = model.fontName { + font = MFFonts.mfFont(withName: fontName, size: fontSize ?? standardFontSize) + } else if let fontSize = fontSize { + font = font?.updateSize(fontSize) + } + } + if isEditable { MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 6b335614..a4660b54 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -100,8 +100,8 @@ open class TextViewModel: MoleculeModelProtocol { borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .accessibilityText) - fontName = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) + fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize) + fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index 6accea28..a1e49927 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -294,6 +294,7 @@ B3 -> Legal /// Will style the label based on the string. Accepted values, including mva3.0 fonts and 2.0 fonts H1, H2, H3, H32, B1, B2, B3, B20 + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style; + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; ++ (void)styleTextView:(nonnull UITextView *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label; diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index 213c205e..2805d4ee 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -853,6 +853,28 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; } } ++ (void)styleTextView:(nonnull UITextView *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { + if ([self styleMVA3Label:label withStyle:style genericScaling:genericScaling]) { + //try mva 3.0 font first + } else if ([style isEqualToString:@"H1"]) { + [self styleLabelH1:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"H2"]) { + [self styleLabelH2:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"H3"]) { + [self styleLabelH3:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"H32"]) { + [self styleLabelH32:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"B1"]) { + [self styleLabelB1:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"B3"]) { + [self styleLabelB3:label genericScaling:genericScaling]; + } else if ([style isEqualToString:@"B20"]) { + [self styleLabelB20:label genericScaling:genericScaling]; + } else { + [self styleLabelB2:label genericScaling:genericScaling]; + } +} + + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style { [self styleLabel:label withStyle:style genericScaling:YES]; } From 4fb8e05498be74323d9dd0b4d442dc655f9b2323 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 9 Apr 2020 15:44:45 -0400 Subject: [PATCH 08/25] now --- MVMCoreUI/BaseClasses/TextView.swift | 40 ++++++++++++----------- MVMCoreUI/BaseClasses/TextViewModel.swift | 11 ++++--- MVMCoreUI/Styles/MFStyler.h | 1 - MVMCoreUI/Styles/MFStyler.m | 22 ------------- MVMCoreUI/Styles/Styler.swift | 2 +- 5 files changed, 29 insertions(+), 47 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 735abfaf..b0076c09 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -26,8 +26,10 @@ import UIKit /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false - private var textTraits: (color: UIColor, font: UIFont) = (color: .mvmBlack, font: MFStyler.fontRegularBodySmall()) - private var placeholderTraits: (text: String, color: UIColor, font: UIFont) = (text: "", color: .mvmCoolGray3, font: MFStyler.fontRegularMicro() ) + private var textTraits: (color: UIColor, font: UIFont) = (color: .mvmBlack, + font: Styler.Font.RegularBodySmall.getFont()) + private var placeholderTraits: (text: String, color: UIColor, font: UIFont) = (text: "", + color: .mvmCoolGray3, font: Styler.Font.RegularMicro.getFont()) //-------------------------------------------------- // MARK: - Delegate @@ -201,9 +203,9 @@ extension TextView: MoleculeViewProtocol { textColor = model.textColor.uiColor layer.borderColor = model.borderColor?.cgColor layer.borderWidth = model.borderWidth -// placeholderFont = model.placeholderFont text = model.text isShowingPlaceholder = model.text.isEmpty + placeholderTraits.font = model.placeholderFont.getFont() placeholderTraits.text = model.placeholder uiTextViewDelegate = delegateObject?.uiTextViewDelegate @@ -211,22 +213,22 @@ extension TextView: MoleculeViewProtocol { accessibilityLabel = accessibilityText } - if let fontStyle = model.fontStyle?.rawValue { - MFStyler.styleTextView(self, withStyle: fontStyle, genericScaling: false) - standardFontSize = font?.pointSize ?? 0 - if let font = font { - textTraits.font = font - } - } else { - let fontSize = model.fontSize - if let fontSize = fontSize { - standardFontSize = fontSize - } - if let fontName = model.fontName { - font = MFFonts.mfFont(withName: fontName, size: fontSize ?? standardFontSize) - } else if let fontSize = fontSize { - font = font?.updateSize(fontSize) - } + font = model.fontStyle.getFont() + standardFontSize = model.fontStyle.pointSize() + if let font = font { + textTraits.font = font + } + + let fontSize = model.fontSize + if let fontSize = fontSize { + standardFontSize = fontSize + } + if let fontName = model.fontName { + font = Styler.Font(rawValue: fontName)?.getFont() + textTraits.font = font! + } else if let fontSize = fontSize { + font = font?.updateSize(fontSize) + textTraits.font = font! } if isEditable { diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index a4660b54..7cff3119 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -21,11 +21,11 @@ open class TextViewModel: MoleculeModelProtocol { public var textColor: Color = Color(uiColor: .mvmBlack) public var fontSize: CGFloat? public var fontName: String? - public var fontStyle: LabelModel.FontStyle? + public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left public var height: CGFloat? public var placeholder: String = "" - public var placeholderFont: LabelModel.FontStyle = LabelModel.FontStyle.RegularMicro + public var placeholderFont: Styler.Font = Styler.Font.RegularMicro public var isEditable: Bool = true public var borderColor: Color? public var borderWidth: CGFloat = 0 @@ -77,7 +77,7 @@ open class TextViewModel: MoleculeModelProtocol { self.placeholder = placeholder } - if let placeholderFont = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .placeholderFont) { + if let placeholderFont = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .placeholderFont) { self.placeholderFont = placeholderFont } @@ -97,12 +97,15 @@ open class TextViewModel: MoleculeModelProtocol { self.borderWidth = borderWidth } + if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { + self.fontStyle = fontStyle + } + borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize) fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) - fontStyle = try typeContainer.decodeIfPresent(LabelModel.FontStyle.self, forKey: .fontStyle) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index a1e49927..6accea28 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -294,7 +294,6 @@ B3 -> Legal /// Will style the label based on the string. Accepted values, including mva3.0 fonts and 2.0 fonts H1, H2, H3, H32, B1, B2, B3, B20 + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style; + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; -+ (void)styleTextView:(nonnull UITextView *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label genericScaling:(BOOL)genericScaling; + (void)styleLabelH1:(nonnull UILabel *)label; diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index 2805d4ee..213c205e 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -853,28 +853,6 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; } } -+ (void)styleTextView:(nonnull UITextView *)label withStyle:(nullable NSString *)style genericScaling:(BOOL)genericScaling { - if ([self styleMVA3Label:label withStyle:style genericScaling:genericScaling]) { - //try mva 3.0 font first - } else if ([style isEqualToString:@"H1"]) { - [self styleLabelH1:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"H2"]) { - [self styleLabelH2:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"H3"]) { - [self styleLabelH3:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"H32"]) { - [self styleLabelH32:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"B1"]) { - [self styleLabelB1:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"B3"]) { - [self styleLabelB3:label genericScaling:genericScaling]; - } else if ([style isEqualToString:@"B20"]) { - [self styleLabelB20:label genericScaling:genericScaling]; - } else { - [self styleLabelB2:label genericScaling:genericScaling]; - } -} - + (void)styleLabel:(nonnull UILabel *)label withStyle:(nullable NSString *)style { [self styleLabel:label withStyle:style genericScaling:YES]; } diff --git a/MVMCoreUI/Styles/Styler.swift b/MVMCoreUI/Styles/Styler.swift index b5d6627c..849395b1 100644 --- a/MVMCoreUI/Styles/Styler.swift +++ b/MVMCoreUI/Styles/Styler.swift @@ -144,7 +144,7 @@ open class Styler { } /// Returns the font based on the declared enum case. - public func getFont(_ genericScaling: Bool = true) -> UIFont? { + public func getFont(_ genericScaling: Bool = true) -> UIFont { let size = genericScaling ? sizeFontGeneric(forCurrentDevice: pointSize()) : pointSize() From 66374f85ced5a0b1f531c77c994ea1229a684030 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 10 Apr 2020 10:40:05 -0400 Subject: [PATCH 09/25] textView functioning --- .../Atomic/Atoms/TextFields/DigitBox.swift | 2 +- MVMCoreUI/BaseClasses/TextField.swift | 5 +- MVMCoreUI/BaseClasses/TextView.swift | 100 +++++++++--------- MVMCoreUI/BaseClasses/TextViewModel.swift | 32 +++--- 4 files changed, 68 insertions(+), 71 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift index 1134a80f..a155c5bd 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift @@ -13,7 +13,7 @@ import UIKit } -@objcMembers open class DigitBox: EntryFieldContainer, UITextFieldDelegate, TextFieldDidDeleteProtocol { +@objcMembers open class DigitBox: EntryFieldContainer, UITextFieldDelegate, TextInputDidDeleteProtocol { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- diff --git a/MVMCoreUI/BaseClasses/TextField.swift b/MVMCoreUI/BaseClasses/TextField.swift index c571d52d..ea56e68e 100644 --- a/MVMCoreUI/BaseClasses/TextField.swift +++ b/MVMCoreUI/BaseClasses/TextField.swift @@ -8,7 +8,7 @@ import UIKit -public protocol TextFieldDidDeleteProtocol: class { +public protocol TextInputDidDeleteProtocol: class { func textFieldDidDelete() } @@ -17,6 +17,7 @@ public protocol TextFieldDidDeleteProtocol: class { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- + private var initialSetupPerformed = false /// Set to true to hide the blinking textField cursor. @@ -27,7 +28,7 @@ public protocol TextFieldDidDeleteProtocol: class { //-------------------------------------------------- /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. - public weak var didDeleteDelegate: TextFieldDidDeleteProtocol? + public weak var didDeleteDelegate: TextInputDidDeleteProtocol? //-------------------------------------------------- // MARK: - Initialization diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index b0076c09..977dcfe8 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -18,30 +18,27 @@ import UIKit private var initialSetupPerformed = false - /// Set this property if you want updateView to update the font based on this standard and the size passed in. - public var standardFontSize: CGFloat = 0.0 - + /// If true then text textView is currently displaying the stored placeholder text as there is not content to display. public var isShowingPlaceholder = true /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false - private var textTraits: (color: UIColor, font: UIFont) = (color: .mvmBlack, - font: Styler.Font.RegularBodySmall.getFont()) - private var placeholderTraits: (text: String, color: UIColor, font: UIFont) = (text: "", - color: .mvmCoolGray3, font: Styler.Font.RegularMicro.getFont()) + public var textViewModel: TextViewModel? { + return model as? TextViewModel + } //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. - public weak var didDeleteDelegate: TextFieldDidDeleteProtocol? + public weak var didDeleteDelegate: TextInputDidDeleteProtocol? /// Holds a reference to the delegating class so this class can internally influence the TextField behavior as well. private weak var proprietorTextDelegate: UITextViewDelegate? - /// If you're using a ViewController, you must set this to it + /// If you're using a ViewController, you must set this to it. public weak var uiTextViewDelegate: UITextViewDelegate? { get { return delegate } set { @@ -74,12 +71,15 @@ import UIKit initialSetup() } - convenience init(placeholderText: String, delegate: UITextViewDelegate?) { + convenience init(delegate: UITextViewDelegate) { self.init(frame: .zero, textContainer: nil) self.delegate = delegate - self.placeholderTraits.text = placeholderText } + //-------------------------------------------------- + // MARK: - Setup + //-------------------------------------------------- + public func initialSetup() { if !initialSetupPerformed { @@ -89,6 +89,11 @@ import UIKit } } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Alters the blinking caret line as per design standards. open override func caretRect(for position: UITextPosition) -> CGRect { if hideBlinkingCaret { @@ -104,26 +109,40 @@ import UIKit didDeleteDelegate?.textFieldDidDelete() } - open func setTextViewState() { + public func setTextAppearance() { if isShowingPlaceholder { - text = "" - font = textTraits.font - textColor = textTraits.color - isShowingPlaceholder = false - } else if text.isEmpty { - isShowingPlaceholder = true - textColor = placeholderTraits.color - text = placeholderTraits.text - font = placeholderTraits.font + setTextContentTraits() } } + public func setPlaceholderIfAvailable() { + + if let placeholder = textViewModel?.placeholder, !placeholder.isEmpty && text.isEmpty { + setPlaceholderContentTraits() + } + } + + public func setTextContentTraits() { + + isShowingPlaceholder = false + text = "" + font = textViewModel?.fontStyle.getFont() + textColor = textViewModel?.textColor.uiColor + } + + public func setPlaceholderContentTraits() { + + isShowingPlaceholder = true + textColor = textViewModel?.placeholderTextColor.uiColor + font = textViewModel?.placeholderFontStyle.getFont() + text = textViewModel?.placeholder + } + //-------------------------------------------------- // MARK: - UITextViewDelegate //-------------------------------------------------- - //#pragma Mark UITextView Delegate methods forwarding @objc public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { return proprietorTextDelegate?.textViewShouldBeginEditing?(textView) ?? true @@ -131,6 +150,7 @@ import UIKit @objc public func textViewDidBeginEditing(_ textView: UITextView) { + setTextAppearance() proprietorTextDelegate?.textViewDidBeginEditing?(textView) } @@ -141,8 +161,6 @@ import UIKit @objc public func textViewDidChange(_ textView: UITextView) { - setTextViewState() - proprietorTextDelegate?.textViewDidChange?(textView) } @@ -153,6 +171,7 @@ import UIKit @objc public func textViewDidEndEditing(_ textView: UITextView) { + setPlaceholderIfAvailable() proprietorTextDelegate?.textViewDidEndEditing?(textView) } } @@ -174,7 +193,7 @@ extension TextView: MVMCoreViewProtocol { smartQuotesType = .no smartDashesType = .no smartInsertDeleteType = .no - font = textTraits.font + font = textViewModel?.fontStyle.getFont() layer.borderWidth = 1 layer.borderColor = UIColor.mvmBlack.cgColor isEditable = true @@ -193,10 +212,8 @@ extension TextView: MoleculeViewProtocol { guard let model = model as? TextViewModel else { return } - if let height = model.height { - heightConstraint = heightAnchor.constraint(equalToConstant: height) - heightConstraint?.isActive = true - } + heightConstraint = heightAnchor.constraint(equalToConstant: model.height) + heightConstraint?.isActive = true isEditable = model.isEditable textAlignment = model.textAlignment @@ -204,32 +221,15 @@ extension TextView: MoleculeViewProtocol { layer.borderColor = model.borderColor?.cgColor layer.borderWidth = model.borderWidth text = model.text - isShowingPlaceholder = model.text.isEmpty - placeholderTraits.font = model.placeholderFont.getFont() - placeholderTraits.text = model.placeholder uiTextViewDelegate = delegateObject?.uiTextViewDelegate + isShowingPlaceholder = model.text.isEmpty if let accessibilityText = model.accessibilityText { accessibilityLabel = accessibilityText } font = model.fontStyle.getFont() - standardFontSize = model.fontStyle.pointSize() - if let font = font { - textTraits.font = font - } - - let fontSize = model.fontSize - if let fontSize = fontSize { - standardFontSize = fontSize - } - if let fontName = model.fontName { - font = Styler.Font(rawValue: fontName)?.getFont() - textTraits.font = font! - } else if let fontSize = fontSize { - font = font?.updateSize(fontSize) - textTraits.font = font! - } + setPlaceholderIfAvailable() if isEditable { MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) @@ -238,8 +238,10 @@ extension TextView: MoleculeViewProtocol { open func reset() { - setNeedsDisplay() backgroundColor = .clear text = "" + inputAccessoryView?.removeFromSuperview() + layer.borderColor = UIColor.mvmBlack.cgColor + layer.borderWidth = 0 } } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 7cff3119..296e2ea8 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -16,20 +16,19 @@ open class TextViewModel: MoleculeModelProtocol { public static var identifier: String = "textView" public var backgroundColor: Color? - public var text: String = "" public var accessibilityText: String? + public var text: String = "" public var textColor: Color = Color(uiColor: .mvmBlack) - public var fontSize: CGFloat? - public var fontName: String? public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left - public var height: CGFloat? + public var height: CGFloat public var placeholder: String = "" - public var placeholderFont: Styler.Font = Styler.Font.RegularMicro + public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3) + public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro + public var showsPlaceholder: Bool = true public var isEditable: Bool = true public var borderColor: Color? public var borderWidth: CGFloat = 0 - public var showsPlaceholder: Bool = true //-------------------------------------------------- // MARK: - Keys @@ -42,15 +41,13 @@ open class TextViewModel: MoleculeModelProtocol { case accessibilityText case textColor case fontStyle - case fontSize - case fontName case textAlignment case attributes case height case borderColor case borderWidth case placeholder - case placeholderFont + case placeholderFontStyle case isEditable } @@ -58,7 +55,8 @@ open class TextViewModel: MoleculeModelProtocol { // MARK: - Initializer //-------------------------------------------------- - public init(text: String) { + public init(height: CGFloat, text: String = "") { + self.height = height self.text = text } @@ -77,8 +75,8 @@ open class TextViewModel: MoleculeModelProtocol { self.placeholder = placeholder } - if let placeholderFont = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .placeholderFont) { - self.placeholderFont = placeholderFont + if let placeholderFontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .placeholderFontStyle) { + self.placeholderFontStyle = placeholderFontStyle } if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { @@ -104,9 +102,7 @@ open class TextViewModel: MoleculeModelProtocol { borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - fontSize = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .fontSize) - fontName = try typeContainer.decodeIfPresent(String.self, forKey: .fontName) - height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) + height = try typeContainer.decode(CGFloat.self, forKey: .height) } public func encode(to encoder: Encoder) throws { @@ -116,13 +112,11 @@ open class TextViewModel: MoleculeModelProtocol { try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) - try container.encodeIfPresent(height, forKey: .height) try container.encodeIfPresent(borderColor, forKey: .borderColor) - try container.encodeIfPresent(fontSize, forKey: .fontSize) - try container.encodeIfPresent(fontName, forKey: .fontName) + try container.encode(height, forKey: .height) try container.encode(text, forKey: .text) try container.encode(placeholder, forKey: .placeholder) - try container.encode(placeholderFont, forKey: .placeholderFont) + try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(textAlignment, forKey: .textAlignment) try container.encode(isEditable, forKey: .isEditable) try container.encode(borderWidth, forKey: .borderWidth) From 10a654f107b5fdd3f83d2545ef981b546f1637f1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 10 Apr 2020 11:34:55 -0400 Subject: [PATCH 10/25] changed for dismiss button. --- MVMCoreUI/BaseControllers/ScrollingViewController.swift | 2 +- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ScrollingViewController.swift b/MVMCoreUI/BaseControllers/ScrollingViewController.swift index 2e4eceef..6831f9c0 100644 --- a/MVMCoreUI/BaseControllers/ScrollingViewController.swift +++ b/MVMCoreUI/BaseControllers/ScrollingViewController.swift @@ -36,7 +36,7 @@ open class ScrollingViewController: ViewController { super.viewDidLoad() // Adds the tap gesture to dismiss the keyboard. - dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput(sender:))) + dismissKeyboardTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissFieldInput(_:))) view.addGestureRecognizer(dismissKeyboardTapGesture!) dismissKeyboardTapGesture?.isEnabled = false scrollView.alwaysBounceVertical = false diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index ab143b14..c7d8e241 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -398,7 +398,7 @@ import UIKit } } - @objc open func dismissFieldInput(sender: Any?) { + @objc open func dismissFieldInput(_ sender: Any?) { selectedField?.resignFirstResponder() } From b1293ad9ed15f2374b2d6ba8c9b38ad5ac229ccf Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 15 Apr 2020 14:03:59 -0400 Subject: [PATCH 11/25] changes amde --- MVMCoreUI/BaseClasses/TextView.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 977dcfe8..1046e327 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -161,6 +161,7 @@ import UIKit @objc public func textViewDidChange(_ textView: UITextView) { + textViewModel?.text = textView.text proprietorTextDelegate?.textViewDidChange?(textView) } @@ -188,7 +189,8 @@ extension TextView: MVMCoreViewProtocol { insetsLayoutMarginsFromSafeArea = false showsVerticalScrollIndicator = false showsHorizontalScrollIndicator = false - backgroundColor = .clear + contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) + backgroundColor = .mvmWhite clipsToBounds = true smartQuotesType = .no smartDashesType = .no @@ -212,6 +214,7 @@ extension TextView: MoleculeViewProtocol { guard let model = model as? TextViewModel else { return } + heightConstraint?.isActive = false heightConstraint = heightAnchor.constraint(equalToConstant: model.height) heightConstraint?.isActive = true @@ -238,10 +241,11 @@ extension TextView: MoleculeViewProtocol { open func reset() { - backgroundColor = .clear + backgroundColor = .mvmWhite text = "" inputAccessoryView?.removeFromSuperview() layer.borderColor = UIColor.mvmBlack.cgColor + contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) layer.borderWidth = 0 } } From 8a8bc84f9967ee29b28d0d51a6f45ddafd90a23d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Apr 2020 13:04:13 -0400 Subject: [PATCH 12/25] three layer fill --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++++++++---- .../ThreeLayerFillMiddleTemplate.swift | 21 +++++++++++++++++++ .../ThreeLayerFillMiddleTemplateModel.swift | 15 +++++++++++++ .../Atomic/Templates/ThreeLayerTemplate.swift | 4 ++++ MVMCoreUI/BaseClasses/TextView.swift | 6 ++++-- MVMCoreUI/BaseClasses/TextViewModel.swift | 6 +++--- ...iewControllerMappingObject+Extension.swift | 1 + 7 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift create mode 100644 MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 2c760af1..663967c0 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -86,10 +86,10 @@ 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; 0A6682A22434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */; }; 0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */; }; - 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; }; - 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */; }; 0A6682AA2435125F00AD3CA1 /* Styler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682A92435125F00AD3CA1 /* Styler.swift */; }; 0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682AB243531C300AD3CA1 /* Padding.swift */; }; + 0A6682B5243769C700AD3CA1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B3243769C700AD3CA1 /* TextView.swift */; }; + 0A6682B6243769C700AD3CA1 /* TextViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */; }; 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; @@ -310,6 +310,8 @@ D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */; }; D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; }; D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; }; + D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */; }; + D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */; }; D28A837923C7D5BC00DFE4FC /* PageModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */; }; D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */; }; D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */; }; @@ -539,10 +541,10 @@ 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; 0A6682A12434DB4F00AD3CA1 /* ListLeftVariableRadioButtonBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyText.swift; sourceTree = ""; }; 0A6682A32434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonBodyTextModel.swift; sourceTree = ""; }; - 0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; - 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewModel.swift; sourceTree = ""; }; 0A6682A92435125F00AD3CA1 /* Styler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Styler.swift; sourceTree = ""; }; 0A6682AB243531C300AD3CA1 /* Padding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Padding.swift; sourceTree = ""; }; + 0A6682B3243769C700AD3CA1 /* TextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; + 0A6682B4243769C700AD3CA1 /* TextViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextViewModel.swift; sourceTree = ""; }; 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = ""; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; @@ -764,6 +766,8 @@ D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = ""; }; D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = ""; }; D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = ""; }; + D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplate.swift; sourceTree = ""; }; + D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerFillMiddleTemplateModel.swift; sourceTree = ""; }; D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageModelProtocol.swift; sourceTree = ""; }; D28A837A23C928DA00DFE4FC /* MoleculeListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListCellProtocol.swift; sourceTree = ""; }; D28A837C23CCA86A00DFE4FC /* TabsListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsListItemModel.swift; sourceTree = ""; }; @@ -1580,6 +1584,8 @@ D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */, D2092350244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift */, D209234E244F77FD0044AD09 /* ThreeLayerCenterTemplate.swift */, + D28764AB245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift */, + D28764A92458980300CB882D /* ThreeLayerFillMiddleTemplate.swift */, D264FAA4243F66A500D98315 /* CollectionTemplateItemProtocol.swift */, D264FA8B243BCD8E00D98315 /* CollectionTemplateModel.swift */, D264FA8D243BCD9A00D98315 /* CollectionTemplate.swift */, @@ -2159,6 +2165,7 @@ 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */, D2FB151D23A40F1500C20E10 /* MoleculeStackItem.swift in Sources */, AA11A41F23F15D3100D7962F /* ListRightVariablePayments.swift in Sources */, + D28764AA2458980300CB882D /* ThreeLayerFillMiddleTemplate.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */, D2092353244F7D630044AD09 /* MVMCoreUIViewControllerMappingObject+Extension.swift in Sources */, @@ -2210,6 +2217,7 @@ AA617AB22453012400910B8F /* ListDeviceComplexLinkSmallModel.swift in Sources */, D260106323D0C05000764D80 /* StackItemModel.swift in Sources */, D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */, + D28764AC245898A400CB882D /* ThreeLayerFillMiddleTemplateModel.swift in Sources */, BBBBC87D24374A4900B0F079 /* ListThreeColumnBillChangesDividerModel.swift in Sources */, D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift new file mode 100644 index 00000000..50e55a45 --- /dev/null +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift @@ -0,0 +1,21 @@ +// +// ThreeLayerFillMiddleTemplate.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +@objcMembers open class ThreeLayerFillMiddleTemplate: ThreeLayerTemplate { + open override func spaceBetweenMiddleAndBottom() -> CGFloat? { + return 0 + } + + open override func handleNewData() { + super.handleNewData() + heightConstraint?.isActive = true + } +} diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift new file mode 100644 index 00000000..7ea1aa70 --- /dev/null +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift @@ -0,0 +1,15 @@ +// +// ThreeLayerFillMiddleTemplateModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/28/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class ThreeLayerFillMiddleTemplateModel: ThreeLayerPageTemplateModel { + public override class var identifier: String { + return "threeLayerFillMiddle" + } +} diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift index 4884d5b1..c393297b 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift @@ -49,4 +49,8 @@ import UIKit open override func spaceBetweenTopAndMiddle() -> CGFloat? { return 0 } + + open override func spaceBetweenMiddleAndBottom() -> CGFloat? { + return nil + } } diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 1046e327..d83ba684 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -215,8 +215,10 @@ extension TextView: MoleculeViewProtocol { guard let model = model as? TextViewModel else { return } heightConstraint?.isActive = false - heightConstraint = heightAnchor.constraint(equalToConstant: model.height) - heightConstraint?.isActive = true + if let height = model.height { + heightConstraint = heightAnchor.constraint(equalToConstant: height) + heightConstraint?.isActive = true + } isEditable = model.isEditable textAlignment = model.textAlignment diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 296e2ea8..d69fcc75 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -21,7 +21,7 @@ open class TextViewModel: MoleculeModelProtocol { public var textColor: Color = Color(uiColor: .mvmBlack) public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left - public var height: CGFloat + public var height: CGFloat? public var placeholder: String = "" public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3) public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro @@ -102,7 +102,7 @@ open class TextViewModel: MoleculeModelProtocol { borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - height = try typeContainer.decode(CGFloat.self, forKey: .height) + height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } public func encode(to encoder: Encoder) throws { @@ -113,7 +113,7 @@ open class TextViewModel: MoleculeModelProtocol { try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) try container.encodeIfPresent(borderColor, forKey: .borderColor) - try container.encode(height, forKey: .height) + try container.encodeIfPresent(height, forKey: .height) try container.encode(text, forKey: .text) try container.encode(placeholder, forKey: .placeholder) try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift index 5cb2abdb..36f13be0 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIViewControllerMappingObject+Extension.swift @@ -23,6 +23,7 @@ public extension MVMCoreUIViewControllerMappingObject { register(template: ThreeLayerTemplate.self) register(template: ThreeLayerCenterTemplate.self) + register(template: ThreeLayerFillMiddleTemplate.self) register(template: CollectionTemplate.self) } From bc477d9da671953c1699cd4ca5bcd7a9018cf921 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 28 Apr 2020 13:06:49 -0400 Subject: [PATCH 13/25] updating to align with android. changing super. --- .../TextFields/BaseDropdownEntryFieldModel.swift | 2 +- .../TextFields/DateDropdownEntryFieldModel.swift | 2 +- .../Atoms/TextFields/DigitEntryFieldModel.swift | 2 +- .../Atoms/TextFields/EntryFieldModel.swift | 2 +- .../TextFields/ItemDropdownEntryFieldModel.swift | 2 +- .../Atoms/TextFields/MdnEntryFieldModel.swift | 2 +- .../Atoms/TextFields/TextEntryFieldModel.swift | 2 +- MVMCoreUI/BaseClasses/TextViewModel.swift | 16 ++++++++-------- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift index 496625dc..e34183de 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/BaseDropdownEntryFieldModel.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -@objcMembers public class BaseDropdownEntryFieldModel: TextEntryFieldModel { +@objcMembers open class BaseDropdownEntryFieldModel: TextEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift index 86c072dd..96ec3488 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DateDropdownEntryFieldModel.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -@objcMembers public class DateDropdownEntryFieldModel: BaseDropdownEntryFieldModel { +@objcMembers open class DateDropdownEntryFieldModel: BaseDropdownEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift index b906244d..4132a15e 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitEntryFieldModel.swift @@ -7,7 +7,7 @@ // -@objcMembers public class DigitEntryFieldModel: TextEntryFieldModel { +@objcMembers open class DigitEntryFieldModel: TextEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 337d847d..4d99a2d8 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -9,7 +9,7 @@ import Foundation -@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol { +@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift index 2105120c..979fac4d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/ItemDropdownEntryFieldModel.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -@objcMembers public class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel { +@objcMembers open class ItemDropdownEntryFieldModel: BaseDropdownEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift index ea367447..0541de8d 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/MdnEntryFieldModel.swift @@ -6,7 +6,7 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -@objcMembers public class MdnEntryFieldModel: TextEntryFieldModel { +@objcMembers open class MdnEntryFieldModel: TextEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index 0beb2b51..a359dc98 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -7,7 +7,7 @@ // -@objcMembers public class TextEntryFieldModel: EntryFieldModel { +@objcMembers open class TextEntryFieldModel: EntryFieldModel { //-------------------------------------------------- // MARK: - Types //-------------------------------------------------- diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 296e2ea8..8d778a19 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -9,15 +9,16 @@ import Foundation -open class TextViewModel: MoleculeModelProtocol { +open class TextViewModel: TextEntryFieldModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public static var identifier: String = "textView" - public var backgroundColor: Color? + + public override class var identifier: String { + return "textView" + } public var accessibilityText: String? - public var text: String = "" public var textColor: Color = Color(uiColor: .mvmBlack) public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left @@ -48,7 +49,8 @@ open class TextViewModel: MoleculeModelProtocol { case borderWidth case placeholder case placeholderFontStyle - case isEditable + case isEditable = "editable" + case hideBlinkingCaret } //-------------------------------------------------- @@ -98,17 +100,15 @@ open class TextViewModel: MoleculeModelProtocol { if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { self.fontStyle = fontStyle } - + borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) height = try typeContainer.decode(CGFloat.self, forKey: .height) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) - try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) From a685a8d9c40d830e17d065e1e25907c823bab85f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 28 Apr 2020 13:49:57 -0400 Subject: [PATCH 14/25] aligning with android changes --- .../Atoms/TextFields/EntryFieldModel.swift | 1 - MVMCoreUI/BaseClasses/TextView.swift | 2 +- MVMCoreUI/BaseClasses/TextViewModel.swift | 24 +++---------------- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift index 4d99a2d8..a1aca1ad 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/EntryFieldModel.swift @@ -10,7 +10,6 @@ import Foundation @objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, EnableableModelProtocol { - //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index d83ba684..cdebcda4 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -227,7 +227,7 @@ extension TextView: MoleculeViewProtocol { layer.borderWidth = model.borderWidth text = model.text uiTextViewDelegate = delegateObject?.uiTextViewDelegate - isShowingPlaceholder = model.text.isEmpty + isShowingPlaceholder = model.text!.isEmpty if let accessibilityText = model.accessibilityText { accessibilityLabel = accessibilityText diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 6662e360..5efa4b5a 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -14,16 +14,15 @@ open class TextViewModel: TextEntryFieldModel { // MARK: - Properties //-------------------------------------------------- - public override class var identifier: String { return "textView" } + public var accessibilityText: String? public var textColor: Color = Color(uiColor: .mvmBlack) public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left public var height: CGFloat? - public var placeholder: String = "" public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3) public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro public var showsPlaceholder: Bool = true @@ -53,30 +52,14 @@ open class TextViewModel: TextEntryFieldModel { case hideBlinkingCaret } - //-------------------------------------------------- - // MARK: - Initializer - //-------------------------------------------------- - - public init(height: CGFloat, text: String = "") { - self.height = height - self.text = text - } - //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { + try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - if let text = try typeContainer.decodeIfPresent(String.self, forKey: .text) { - self.text = text - } - - if let placeholder = try typeContainer.decodeIfPresent(String.self, forKey: .placeholder) { - self.placeholder = placeholder - } - if let placeholderFontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .placeholderFontStyle) { self.placeholderFontStyle = placeholderFontStyle } @@ -103,11 +86,10 @@ open class TextViewModel: TextEntryFieldModel { borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) - backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } - public func encode(to encoder: Encoder) throws { + public override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) From 2a251649af2356fe2e9e1a488d13a4350f95dd72 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 28 Apr 2020 16:44:05 -0400 Subject: [PATCH 15/25] functioning border --- MVMCoreUI/BaseClasses/TextField.swift | 6 +- MVMCoreUI/BaseClasses/TextView.swift | 326 +++++++++++++++++++--- MVMCoreUI/BaseClasses/TextViewModel.swift | 26 +- 3 files changed, 303 insertions(+), 55 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextField.swift b/MVMCoreUI/BaseClasses/TextField.swift index ea56e68e..03d511dd 100644 --- a/MVMCoreUI/BaseClasses/TextField.swift +++ b/MVMCoreUI/BaseClasses/TextField.swift @@ -51,7 +51,7 @@ public protocol TextInputDidDeleteProtocol: class { public func initialSetup() { if !initialSetupPerformed { - tintColor = .black + tintColor = .mvmBlack initialSetupPerformed = true setupView() } @@ -87,7 +87,9 @@ extension TextField: MVMCoreViewProtocol { /// MARK:- MoleculeViewProtocol extension TextField: MoleculeViewProtocol { - open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { + + open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + if let color = model.backgroundColor?.uiColor { backgroundColor = color } diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index cdebcda4..0a233187 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -9,7 +9,7 @@ import UIKit -@objc open class TextView: UITextView, UITextViewDelegate { +@objc open class TextView: UITextView, UITextViewDelegate, MVMCoreViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -28,6 +28,98 @@ import UIKit return model as? TextViewModel } + //-------------------------------------------------- + // MARK: - Drawing Properties + //-------------------------------------------------- + + /// Total control over the drawn top, bottom, left and right borders. + public var disableAllBorders = false + + 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) + } + } + } + } + + /// 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 _isLocked: Bool = false + private var _isSelected: Bool = false + + public var isEnabled: Bool { + get { return _isEnabled } + set (enabled) { + + _isEnabled = enabled + _isLocked = false + _isSelected = false + _showError = false + + fieldState = enabled ? .original : .disabled + } + } + + public var showError: Bool { + get { return _showError } + set (error) { + + _showError = error + _isEnabled = true + _isLocked = false + _isSelected = false + + fieldState = error ? .error : .original + } + } + + public var isLocked: Bool { + get { return _isLocked } + set (locked) { + + _isLocked = locked + _isEnabled = true + _isSelected = false + _showError = false + + fieldState = locked ? .locked : .original + } + } + + public var isSelected: Bool { + get { return _isSelected } + set (selected) { + + _isSelected = selected + _isLocked = false + _isEnabled = true + + if _showError { + fieldState = selected ? .selectedError : .error + } else { + fieldState = selected ? .selected : .original + } + } + } + //-------------------------------------------------- // MARK: - Delegate //-------------------------------------------------- @@ -47,6 +139,8 @@ import UIKit } } + var delegateObject: MVMCoreUIDelegateObject? + //-------------------------------------------------- // MARK: - Constraint //-------------------------------------------------- @@ -77,7 +171,7 @@ import UIKit } //-------------------------------------------------- - // MARK: - Setup + // MARK: - Lifecycle //-------------------------------------------------- public func initialSetup() { @@ -89,6 +183,187 @@ import UIKit } } + open func updateView(_ size: CGFloat) { + + refreshUI() + } + + /// Will be called only once. + open func setupView() { + + translatesAutoresizingMaskIntoConstraints = false + insetsLayoutMarginsFromSafeArea = false + showsVerticalScrollIndicator = false + showsHorizontalScrollIndicator = false + contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) + backgroundColor = .mvmWhite + clipsToBounds = true + smartQuotesType = .no + smartDashesType = .no + smartInsertDeleteType = .no + font = textViewModel?.fontStyle.getFont() + isEditable = true + isOpaque = false + } + + open func reset() { + + backgroundColor = .mvmWhite + text = "" + inputAccessoryView?.removeFromSuperview() + contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) + } + + open override func layoutSubviews() { + super.layoutSubviews() + + refreshUI(bottomBarSize: showError ? 4 : 1) + } + + //-------------------------------------------------- + // 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 !disableAllBorders && !hideBorders { + // Brings the other half of the line inside the view to prevent cropping. + let origin = bounds.origin + let size = frame.size + let insetLean: CGFloat = 0.5 + borderPath.lineWidth = 1 + + 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() + + bottomPath.lineWidth = 4 + bottomPath.move(to: CGPoint(x: origin.x + size.width, y: origin.y + size.height - 2)) + bottomPath.addLine(to: CGPoint(x: origin.x, y: origin.y + size.height - 2)) + + bottomStrokeColor.setStroke() + bottomPath.stroke() + } + } + + //-------------------------------------------------- + // MARK: - Draw States + //-------------------------------------------------- + + public enum FieldState { + case original + case error + case selectedError + case selected + case locked + case disabled + + public func setStateUI(for formField: TextView) { + + switch self { + case .original: + formField.originalUI() + + case .error: + formField.errorUI() + + case .selectedError: + formField.selectedErrorUI() + + case .selected: + formField.selectedUI() + + case .locked: + formField.lockedUI() + + case .disabled: + formField.disabledUI() + } + } + } + + open func originalUI() { + + isEditable = true + hideBorders = false + borderStrokeColor = .mvmCoolGray3 + bottomStrokeColor = .mvmBlack + refreshUI(bottomBarSize: 1) + } + + open func errorUI() { + + isEditable = true + hideBorders = false + borderStrokeColor = .mvmOrange + bottomStrokeColor = .mvmOrange + refreshUI(bottomBarSize: 4) + } + + open func selectedErrorUI() { + + isEditable = true + hideBorders = false + borderStrokeColor = .mvmBlack + bottomStrokeColor = .mvmOrange + refreshUI(bottomBarSize: 4) + } + + open func selectedUI() { + + isEditable = true + hideBorders = false + borderStrokeColor = .mvmBlack + bottomStrokeColor = .mvmBlack + refreshUI(bottomBarSize: 1) + } + + open func lockedUI() { + + isEditable = false + hideBorders = true + borderStrokeColor = .clear + bottomStrokeColor = .clear + refreshUI(bottomBarSize: 1) + } + + open func disabledUI() { + + isEditable = false + hideBorders = false + borderStrokeColor = .mvmCoolGray3 + bottomStrokeColor = .mvmCoolGray3 + refreshUI(bottomBarSize: 1) + } + + open func refreshUI(bottomBarSize: CGFloat? = nil, updateMoleculeLayout: Bool = false) { + + if !disableAllBorders { +// let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1) +// var heightChanged = false + +// if let bottomHeight = bottomBar?.bounds.height { +// heightChanged = size != bottomHeight +// } + + if updateMoleculeLayout {//|| heightChanged { + delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) + } + + setNeedsDisplay() + layoutIfNeeded() + } + } + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- @@ -177,36 +452,12 @@ import UIKit } } -/// MARK:- MVMCoreViewProtocol -extension TextView: MVMCoreViewProtocol { - - open func updateView(_ size: CGFloat) { } - - /// Will be called only once. - open func setupView() { - - translatesAutoresizingMaskIntoConstraints = false - insetsLayoutMarginsFromSafeArea = false - showsVerticalScrollIndicator = false - showsHorizontalScrollIndicator = false - contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) - backgroundColor = .mvmWhite - clipsToBounds = true - smartQuotesType = .no - smartDashesType = .no - smartInsertDeleteType = .no - font = textViewModel?.fontStyle.getFont() - layer.borderWidth = 1 - layer.borderColor = UIColor.mvmBlack.cgColor - isEditable = true - } -} - -/// MARK:- MoleculeViewProtocol +// MARK:- MoleculeViewProtocol extension TextView: MoleculeViewProtocol { open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { self.model = model + self.delegateObject = delegateObject if let color = model.backgroundColor?.uiColor { backgroundColor = color @@ -223,8 +474,6 @@ extension TextView: MoleculeViewProtocol { isEditable = model.isEditable textAlignment = model.textAlignment textColor = model.textColor.uiColor - layer.borderColor = model.borderColor?.cgColor - layer.borderWidth = model.borderWidth text = model.text uiTextViewDelegate = delegateObject?.uiTextViewDelegate isShowingPlaceholder = model.text!.isEmpty @@ -237,17 +486,14 @@ extension TextView: MoleculeViewProtocol { setPlaceholderIfAvailable() if isEditable { + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) + + if model.selected ?? false { + isSelected = true + model.wasInitiallySelected = true + becomeFirstResponder() + } } } - - open func reset() { - - backgroundColor = .mvmWhite - text = "" - inputAccessoryView?.removeFromSuperview() - layer.borderColor = UIColor.mvmBlack.cgColor - contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) - layer.borderWidth = 0 - } } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 5efa4b5a..017ca1d1 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -27,8 +27,8 @@ open class TextViewModel: TextEntryFieldModel { public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro public var showsPlaceholder: Bool = true public var isEditable: Bool = true - public var borderColor: Color? - public var borderWidth: CGFloat = 0 +// public var borderColor: Color? +// public var borderWidth: CGFloat = 0 //-------------------------------------------------- // MARK: - Keys @@ -44,12 +44,12 @@ open class TextViewModel: TextEntryFieldModel { case textAlignment case attributes case height - case borderColor - case borderWidth - case placeholder +// case borderColor +// case borderWidth +// case placeholder case placeholderFontStyle case isEditable = "editable" - case hideBlinkingCaret +// case hideBlinkingCaret } //-------------------------------------------------- @@ -76,15 +76,15 @@ open class TextViewModel: TextEntryFieldModel { self.isEditable = isEditable } - if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { - self.borderWidth = borderWidth - } +// if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { +// self.borderWidth = borderWidth +// } if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { self.fontStyle = fontStyle } - borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) +// borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } @@ -95,13 +95,13 @@ open class TextViewModel: TextEntryFieldModel { try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) - try container.encodeIfPresent(borderColor, forKey: .borderColor) +// try container.encodeIfPresent(borderColor, forKey: .borderColor) try container.encodeIfPresent(height, forKey: .height) try container.encode(text, forKey: .text) - try container.encode(placeholder, forKey: .placeholder) +// try container.encode(placeholder, forKey: .placeholder) try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(textAlignment, forKey: .textAlignment) try container.encode(isEditable, forKey: .isEditable) - try container.encode(borderWidth, forKey: .borderWidth) +// try container.encode(borderWidth, forKey: .borderWidth) } } From d11260f4536ef802a6ec1a661a57b8d116216e6b Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 28 Apr 2020 18:09:44 -0400 Subject: [PATCH 16/25] remove extra registry --- MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index 8a55c9ad..910ea202 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -179,9 +179,6 @@ import Foundation MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkSmall.self, viewModelClass: ListDeviceComplexLinkSmallModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ListDeviceComplexLinkMedium.self, viewModelClass: ListDeviceComplexLinkMediumModel.self) - // TODO: Need View - try? ModelRegistry.register(TabsModel.self) - // Helper models try? ModelRegistry.register(RuleRequiredModel.self) try? ModelRegistry.register(RuleAnyRequiredModel.self) From 67b8656d63ff9ab7b5eb5a8d6305c346fd0f0c41 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 09:08:08 -0400 Subject: [PATCH 17/25] little fixes and delegate updates. --- .../Atomic/Atoms/TextFields/DigitBox.swift | 2 +- MVMCoreUI/BaseClasses/TextField.swift | 4 +- MVMCoreUI/BaseClasses/TextView.swift | 73 ++++++++----------- MVMCoreUI/BaseClasses/TextViewModel.swift | 17 +---- 4 files changed, 33 insertions(+), 63 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift b/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift index 48ca0e85..ba04f482 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/DigitBox.swift @@ -125,7 +125,7 @@ import UIKit updateView(MVMCoreUIUtility.getWidth()) } - @objc public func textFieldDidDelete() { + @objc public func textInputDidDelete() { digitBoxDelegate?.digitFieldDidDelete?(digitField) } diff --git a/MVMCoreUI/BaseClasses/TextField.swift b/MVMCoreUI/BaseClasses/TextField.swift index 03d511dd..8795054b 100644 --- a/MVMCoreUI/BaseClasses/TextField.swift +++ b/MVMCoreUI/BaseClasses/TextField.swift @@ -9,7 +9,7 @@ import UIKit public protocol TextInputDidDeleteProtocol: class { - func textFieldDidDelete() + func textInputDidDelete() } @@ -69,7 +69,7 @@ public protocol TextInputDidDeleteProtocol: class { open override func deleteBackward() { super.deleteBackward() - didDeleteDelegate?.textFieldDidDelete() + didDeleteDelegate?.textInputDidDelete() } } diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 0a233187..d7840247 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -185,17 +185,22 @@ import UIKit open func updateView(_ size: CGFloat) { - refreshUI() + setNeedsDisplay() } /// Will be called only once. open func setupView() { translatesAutoresizingMaskIntoConstraints = false + initialConfiguration() + } + + public func initialConfiguration() { + insetsLayoutMarginsFromSafeArea = false showsVerticalScrollIndicator = false showsHorizontalScrollIndicator = false - contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) + textContainerInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) backgroundColor = .mvmWhite clipsToBounds = true smartQuotesType = .no @@ -208,16 +213,15 @@ import UIKit open func reset() { - backgroundColor = .mvmWhite text = "" inputAccessoryView?.removeFromSuperview() - contentInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) + initialConfiguration() } open override func layoutSubviews() { super.layoutSubviews() - refreshUI(bottomBarSize: showError ? 4 : 1) + setNeedsDisplay() } //-------------------------------------------------- @@ -246,9 +250,10 @@ import UIKit borderStrokeColor.setStroke() borderPath.stroke() - bottomPath.lineWidth = 4 - bottomPath.move(to: CGPoint(x: origin.x + size.width, y: origin.y + size.height - 2)) - bottomPath.addLine(to: CGPoint(x: origin.x, y: origin.y + size.height - 2)) + 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() @@ -267,27 +272,29 @@ import UIKit case locked case disabled - public func setStateUI(for formField: TextView) { + public func setStateUI(for inputField: TextView) { switch self { case .original: - formField.originalUI() + inputField.originalUI() case .error: - formField.errorUI() + inputField.errorUI() case .selectedError: - formField.selectedErrorUI() + inputField.selectedErrorUI() case .selected: - formField.selectedUI() + inputField.selectedUI() case .locked: - formField.lockedUI() + inputField.lockedUI() case .disabled: - formField.disabledUI() + inputField.disabledUI() } + + inputField.setNeedsDisplay() } } @@ -297,7 +304,6 @@ import UIKit hideBorders = false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmBlack - refreshUI(bottomBarSize: 1) } open func errorUI() { @@ -306,7 +312,6 @@ import UIKit hideBorders = false borderStrokeColor = .mvmOrange bottomStrokeColor = .mvmOrange - refreshUI(bottomBarSize: 4) } open func selectedErrorUI() { @@ -315,7 +320,6 @@ import UIKit hideBorders = false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmOrange - refreshUI(bottomBarSize: 4) } open func selectedUI() { @@ -324,7 +328,6 @@ import UIKit hideBorders = false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmBlack - refreshUI(bottomBarSize: 1) } open func lockedUI() { @@ -333,7 +336,6 @@ import UIKit hideBorders = true borderStrokeColor = .clear bottomStrokeColor = .clear - refreshUI(bottomBarSize: 1) } open func disabledUI() { @@ -342,26 +344,6 @@ import UIKit hideBorders = false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmCoolGray3 - refreshUI(bottomBarSize: 1) - } - - open func refreshUI(bottomBarSize: CGFloat? = nil, updateMoleculeLayout: Bool = false) { - - if !disableAllBorders { -// let size: CGFloat = bottomBarSize ?? (showError ? 4 : 1) -// var heightChanged = false - -// if let bottomHeight = bottomBar?.bounds.height { -// heightChanged = size != bottomHeight -// } - - if updateMoleculeLayout {//|| heightChanged { - delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) - } - - setNeedsDisplay() - layoutIfNeeded() - } } //-------------------------------------------------- @@ -381,7 +363,7 @@ import UIKit open override func deleteBackward() { super.deleteBackward() - didDeleteDelegate?.textFieldDidDelete() + didDeleteDelegate?.textInputDidDelete() } public func setTextAppearance() { @@ -425,6 +407,7 @@ import UIKit @objc public func textViewDidBeginEditing(_ textView: UITextView) { + isSelected = true setTextAppearance() proprietorTextDelegate?.textViewDidBeginEditing?(textView) } @@ -447,6 +430,7 @@ import UIKit @objc public func textViewDidEndEditing(_ textView: UITextView) { + isSelected = false setPlaceholderIfAvailable() proprietorTextDelegate?.textViewDidEndEditing?(textView) } @@ -476,7 +460,7 @@ extension TextView: MoleculeViewProtocol { textColor = model.textColor.uiColor text = model.text uiTextViewDelegate = delegateObject?.uiTextViewDelegate - isShowingPlaceholder = model.text!.isEmpty + isShowingPlaceholder = model.text?.isEmpty ?? false if let accessibilityText = model.accessibilityText { accessibilityLabel = accessibilityText @@ -490,9 +474,10 @@ extension TextView: MoleculeViewProtocol { MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) if model.selected ?? false { - isSelected = true model.wasInitiallySelected = true - becomeFirstResponder() + DispatchQueue.main.async { + self.becomeFirstResponder() + } } } } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 017ca1d1..52764774 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -27,8 +27,6 @@ open class TextViewModel: TextEntryFieldModel { public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro public var showsPlaceholder: Bool = true public var isEditable: Bool = true -// public var borderColor: Color? -// public var borderWidth: CGFloat = 0 //-------------------------------------------------- // MARK: - Keys @@ -42,14 +40,9 @@ open class TextViewModel: TextEntryFieldModel { case textColor case fontStyle case textAlignment - case attributes case height -// case borderColor -// case borderWidth -// case placeholder case placeholderFontStyle case isEditable = "editable" -// case hideBlinkingCaret } //-------------------------------------------------- @@ -76,15 +69,10 @@ open class TextViewModel: TextEntryFieldModel { self.isEditable = isEditable } -// if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { -// self.borderWidth = borderWidth -// } - if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { self.fontStyle = fontStyle } - -// borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) + accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) height = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .height) } @@ -95,13 +83,10 @@ open class TextViewModel: TextEntryFieldModel { try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) -// try container.encodeIfPresent(borderColor, forKey: .borderColor) try container.encodeIfPresent(height, forKey: .height) try container.encode(text, forKey: .text) -// try container.encode(placeholder, forKey: .placeholder) try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(textAlignment, forKey: .textAlignment) try container.encode(isEditable, forKey: .isEditable) -// try container.encode(borderWidth, forKey: .borderWidth) } } From 5f385969943dd34df12ee0b751c07e4fc75e27a7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 10:35:00 -0400 Subject: [PATCH 18/25] further developmet of textView. --- .../TextFields/TextEntryFieldModel.swift | 2 - MVMCoreUI/BaseClasses/TextView.swift | 63 ++++++++----------- MVMCoreUI/BaseClasses/TextViewModel.swift | 12 +--- 3 files changed, 26 insertions(+), 51 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift index a359dc98..d47b9802 100644 --- a/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/TextFields/TextEntryFieldModel.swift @@ -38,7 +38,6 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case placeholder case enabledTextColor case disabledTextColor @@ -67,7 +66,6 @@ public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(placeholder, forKey: .placeholder) try container.encode(enabledTextColor, forKey: .enabledTextColor) try container.encode(disabledTextColor, forKey: .disabledTextColor) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index d7840247..95781aba 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -19,7 +19,10 @@ 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 = true + public var isShowingPlaceholder: Bool { + get { return textViewModel?.showsPlaceholder ?? false } + set { textViewModel?.showsPlaceholder = newValue } + } /// Set to true to hide the blinking textField cursor. public var hideBlinkingCaret = false @@ -62,7 +65,6 @@ import UIKit private var _isEnabled: Bool = true private var _showError: Bool = false - private var _isLocked: Bool = false private var _isSelected: Bool = false public var isEnabled: Bool { @@ -70,7 +72,6 @@ import UIKit set (enabled) { _isEnabled = enabled - _isLocked = false _isSelected = false _showError = false @@ -84,32 +85,17 @@ import UIKit _showError = error _isEnabled = true - _isLocked = false _isSelected = false fieldState = error ? .error : .original } } - public var isLocked: Bool { - get { return _isLocked } - set (locked) { - - _isLocked = locked - _isEnabled = true - _isSelected = false - _showError = false - - fieldState = locked ? .locked : .original - } - } - public var isSelected: Bool { get { return _isSelected } set (selected) { _isSelected = selected - _isLocked = false _isEnabled = true if _showError { @@ -269,7 +255,6 @@ import UIKit case error case selectedError case selected - case locked case disabled public func setStateUI(for inputField: TextView) { @@ -287,9 +272,6 @@ import UIKit case .selected: inputField.selectedUI() - case .locked: - inputField.lockedUI() - case .disabled: inputField.disabledUI() } @@ -300,50 +282,52 @@ import UIKit open func originalUI() { - isEditable = true + isEditable = textViewModel?.isEditable ?? true + isUserInteractionEnabled = true hideBorders = false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmBlack + textColor = textViewModel?.enabledTextColor.uiColor } open func errorUI() { - isEditable = true + isEditable = textViewModel?.isEditable ?? true + isUserInteractionEnabled = true hideBorders = false borderStrokeColor = .mvmOrange bottomStrokeColor = .mvmOrange + textColor = textViewModel?.enabledTextColor.uiColor } open func selectedErrorUI() { - isEditable = true + isEditable = textViewModel?.isEditable ?? true + isUserInteractionEnabled = true hideBorders = false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmOrange + textColor = textViewModel?.enabledTextColor.uiColor } open func selectedUI() { - isEditable = true + isEditable = textViewModel?.isEditable ?? true + isUserInteractionEnabled = true hideBorders = false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmBlack - } - - open func lockedUI() { - - isEditable = false - hideBorders = true - borderStrokeColor = .clear - bottomStrokeColor = .clear + textColor = textViewModel?.enabledTextColor.uiColor } open func disabledUI() { - isEditable = false + isEditable = textViewModel?.isEditable ?? false + isUserInteractionEnabled = false hideBorders = false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmCoolGray3 + textColor = textViewModel?.disabledTextColor.uiColor } //-------------------------------------------------- @@ -385,7 +369,7 @@ import UIKit isShowingPlaceholder = false text = "" font = textViewModel?.fontStyle.getFont() - textColor = textViewModel?.textColor.uiColor + textColor = textViewModel?.enabledTextColor.uiColor } public func setPlaceholderContentTraits() { @@ -457,10 +441,9 @@ extension TextView: MoleculeViewProtocol { isEditable = model.isEditable textAlignment = model.textAlignment - textColor = model.textColor.uiColor + textColor = model.enabledTextColor.uiColor text = model.text uiTextViewDelegate = delegateObject?.uiTextViewDelegate - isShowingPlaceholder = model.text?.isEmpty ?? false if let accessibilityText = model.accessibilityText { accessibilityLabel = accessibilityText @@ -480,5 +463,9 @@ extension TextView: MoleculeViewProtocol { } } } + + if !model.enabled { + isEnabled = false + } } } diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 52764774..e3a8df59 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -19,13 +19,12 @@ open class TextViewModel: TextEntryFieldModel { } public var accessibilityText: String? - public var textColor: Color = Color(uiColor: .mvmBlack) public var fontStyle: Styler.Font = Styler.Font.RegularBodySmall public var textAlignment: NSTextAlignment = .left public var height: CGFloat? public var placeholderTextColor: Color = Color(uiColor: .mvmCoolGray3) public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro - public var showsPlaceholder: Bool = true + public var showsPlaceholder: Bool = false public var isEditable: Bool = true //-------------------------------------------------- @@ -33,11 +32,8 @@ open class TextViewModel: TextEntryFieldModel { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName - case backgroundColor case text case accessibilityText - case textColor case fontStyle case textAlignment case height @@ -61,10 +57,6 @@ open class TextViewModel: TextEntryFieldModel { self.textAlignment = textAlignment } - if let textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor) { - self.textColor = textColor - } - if let isEditable = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEditable) { self.isEditable = isEditable } @@ -79,9 +71,7 @@ open class TextViewModel: TextEntryFieldModel { public override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) - try container.encodeIfPresent(textColor, forKey: .textColor) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) try container.encodeIfPresent(height, forKey: .height) try container.encode(text, forKey: .text) From 19f912512b4ac1310d99f8af601d912e46eba1d2 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 10:55:10 -0400 Subject: [PATCH 19/25] managing hidden border --- MVMCoreUI/BaseClasses/TextView.swift | 16 +++++++--------- MVMCoreUI/BaseClasses/TextViewModel.swift | 7 +++++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 95781aba..fc8695a1 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -35,9 +35,6 @@ import UIKit // MARK: - Drawing Properties //-------------------------------------------------- - /// Total control over the drawn top, bottom, left and right borders. - public var disableAllBorders = false - private(set) var fieldState: FieldState = .original { didSet (oldState) { // Will not update if new state is the same as old. @@ -221,7 +218,7 @@ import UIKit borderPath.removeAllPoints() bottomPath.removeAllPoints() - if !disableAllBorders && !hideBorders { + if !hideBorders { // Brings the other half of the line inside the view to prevent cropping. let origin = bounds.origin let size = frame.size @@ -284,7 +281,7 @@ import UIKit isEditable = textViewModel?.isEditable ?? true isUserInteractionEnabled = true - hideBorders = false + hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmBlack textColor = textViewModel?.enabledTextColor.uiColor @@ -294,7 +291,7 @@ import UIKit isEditable = textViewModel?.isEditable ?? true isUserInteractionEnabled = true - hideBorders = false + hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmOrange bottomStrokeColor = .mvmOrange textColor = textViewModel?.enabledTextColor.uiColor @@ -304,7 +301,7 @@ import UIKit isEditable = textViewModel?.isEditable ?? true isUserInteractionEnabled = true - hideBorders = false + hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmOrange textColor = textViewModel?.enabledTextColor.uiColor @@ -314,7 +311,7 @@ import UIKit isEditable = textViewModel?.isEditable ?? true isUserInteractionEnabled = true - hideBorders = false + hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmBlack bottomStrokeColor = .mvmBlack textColor = textViewModel?.enabledTextColor.uiColor @@ -324,7 +321,7 @@ import UIKit isEditable = textViewModel?.isEditable ?? false isUserInteractionEnabled = false - hideBorders = false + hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmCoolGray3 textColor = textViewModel?.disabledTextColor.uiColor @@ -442,6 +439,7 @@ extension TextView: MoleculeViewProtocol { isEditable = model.isEditable textAlignment = model.textAlignment textColor = model.enabledTextColor.uiColor + hideBorders = model.hideBorders text = model.text uiTextViewDelegate = delegateObject?.uiTextViewDelegate diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index e3a8df59..48b14754 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -25,6 +25,7 @@ open class TextViewModel: TextEntryFieldModel { 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 isEditable: Bool = true //-------------------------------------------------- @@ -37,6 +38,7 @@ open class TextViewModel: TextEntryFieldModel { case fontStyle case textAlignment case height + case hideBorders case placeholderFontStyle case isEditable = "editable" } @@ -57,6 +59,10 @@ open class TextViewModel: TextEntryFieldModel { self.textAlignment = textAlignment } + if let hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) { + self.hideBorders = hideBorders + } + if let isEditable = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEditable) { self.isEditable = isEditable } @@ -74,6 +80,7 @@ open class TextViewModel: TextEntryFieldModel { try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(fontStyle, forKey: .fontStyle) try container.encodeIfPresent(height, forKey: .height) + try container.encodeIfPresent(hideBorders, forKey: .hideBorders) try container.encode(text, forKey: .text) try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(textAlignment, forKey: .textAlignment) From 8bb6a7fb1d078c4af10dbcce574e106c08164b7f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 11:23:49 -0400 Subject: [PATCH 20/25] latest state of text view --- MVMCoreUI/BaseClasses/TextView.swift | 26 +++++++++++++++++------ MVMCoreUI/BaseClasses/TextViewModel.swift | 6 ++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index fc8695a1..9136424f 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -19,9 +19,8 @@ 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 { - get { return textViewModel?.showsPlaceholder ?? false } - set { textViewModel?.showsPlaceholder = newValue } + public var isShowingPlaceholder: Bool = false { + didSet { textViewModel?.showsPlaceholder = isShowingPlaceholder } } /// Set to true to hide the blinking textField cursor. @@ -183,6 +182,7 @@ import UIKit insetsLayoutMarginsFromSafeArea = false showsVerticalScrollIndicator = false showsHorizontalScrollIndicator = false + isSecureTextEntry = false textContainerInset = UIEdgeInsets(top: Padding.Three, left: Padding.Three, bottom: Padding.Three, right: Padding.Three) backgroundColor = .mvmWhite clipsToBounds = true @@ -219,12 +219,13 @@ import UIKit bottomPath.removeAllPoints() if !hideBorders { - // Brings the other half of the line inside the view to prevent cropping. + // 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)) @@ -284,7 +285,7 @@ import UIKit hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmCoolGray3 bottomStrokeColor = .mvmBlack - textColor = textViewModel?.enabledTextColor.uiColor + textColor = isShowingPlaceholder ? textViewModel?.placeholderTextColor.uiColor : textViewModel?.enabledTextColor.uiColor } open func errorUI() { @@ -388,8 +389,8 @@ import UIKit @objc public func textViewDidBeginEditing(_ textView: UITextView) { - isSelected = true setTextAppearance() + isSelected = true proprietorTextDelegate?.textViewDidBeginEditing?(textView) } @@ -411,8 +412,8 @@ import UIKit @objc public func textViewDidEndEditing(_ textView: UITextView) { - isSelected = false setPlaceholderIfAvailable() + isSelected = false proprietorTextDelegate?.textViewDidEndEditing?(textView) } } @@ -447,6 +448,17 @@ extension TextView: MoleculeViewProtocol { accessibilityLabel = accessibilityText } + switch model.type { + case .secure, .password: + isSecureTextEntry = true + case .number: + keyboardType = .numberPad + case .email: + keyboardType = .emailAddress + default: + break + } + font = model.fontStyle.getFont() setPlaceholderIfAvailable() diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 48b14754..3574d2b9 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -40,6 +40,7 @@ open class TextViewModel: TextEntryFieldModel { case height case hideBorders case placeholderFontStyle + case placeholderTextColor case isEditable = "editable" } @@ -55,6 +56,10 @@ open class TextViewModel: TextEntryFieldModel { self.placeholderFontStyle = placeholderFontStyle } + if let placeholderTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .placeholderTextColor) { + self.placeholderTextColor = placeholderTextColor + } + if let textAlignment = try typeContainer.decodeIfPresent(NSTextAlignment.self, forKey: .textAlignment) { self.textAlignment = textAlignment } @@ -83,6 +88,7 @@ open class TextViewModel: TextEntryFieldModel { try container.encodeIfPresent(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(isEditable, forKey: .isEditable) } From 7a9d7d89194d836f0478a9f8cb1eb23be8ffe2e1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 11:27:53 -0400 Subject: [PATCH 21/25] altered isEditable to editable to align with android --- MVMCoreUI/BaseClasses/TextView.swift | 12 ++++++------ MVMCoreUI/BaseClasses/TextViewModel.swift | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 9136424f..6d3a3d7f 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -280,7 +280,7 @@ import UIKit open func originalUI() { - isEditable = textViewModel?.isEditable ?? true + isEditable = textViewModel?.editable ?? true isUserInteractionEnabled = true hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmCoolGray3 @@ -290,7 +290,7 @@ import UIKit open func errorUI() { - isEditable = textViewModel?.isEditable ?? true + isEditable = textViewModel?.editable ?? true isUserInteractionEnabled = true hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmOrange @@ -300,7 +300,7 @@ import UIKit open func selectedErrorUI() { - isEditable = textViewModel?.isEditable ?? true + isEditable = textViewModel?.editable ?? true isUserInteractionEnabled = true hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmBlack @@ -310,7 +310,7 @@ import UIKit open func selectedUI() { - isEditable = textViewModel?.isEditable ?? true + isEditable = textViewModel?.editable ?? true isUserInteractionEnabled = true hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmBlack @@ -320,7 +320,7 @@ import UIKit open func disabledUI() { - isEditable = textViewModel?.isEditable ?? false + isEditable = textViewModel?.editable ?? false isUserInteractionEnabled = false hideBorders = textViewModel?.hideBorders ?? false borderStrokeColor = .mvmCoolGray3 @@ -437,7 +437,7 @@ extension TextView: MoleculeViewProtocol { heightConstraint?.isActive = true } - isEditable = model.isEditable + isEditable = model.editable textAlignment = model.textAlignment textColor = model.enabledTextColor.uiColor hideBorders = model.hideBorders diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 3574d2b9..1972e60f 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -26,7 +26,7 @@ open class TextViewModel: TextEntryFieldModel { public var placeholderFontStyle: Styler.Font = Styler.Font.RegularMicro public var showsPlaceholder: Bool = false public var hideBorders: Bool = false - public var isEditable: Bool = true + public var editable: Bool = true //-------------------------------------------------- // MARK: - Keys @@ -41,7 +41,7 @@ open class TextViewModel: TextEntryFieldModel { case hideBorders case placeholderFontStyle case placeholderTextColor - case isEditable = "editable" + case editable } //-------------------------------------------------- @@ -68,8 +68,8 @@ open class TextViewModel: TextEntryFieldModel { self.hideBorders = hideBorders } - if let isEditable = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEditable) { - self.isEditable = isEditable + if let editable = try typeContainer.decodeIfPresent(Bool.self, forKey: .editable) { + self.editable = editable } if let fontStyle = try typeContainer.decodeIfPresent(Styler.Font.self, forKey: .fontStyle) { @@ -90,6 +90,6 @@ open class TextViewModel: TextEntryFieldModel { try container.encode(placeholderFontStyle, forKey: .placeholderFontStyle) try container.encode(placeholderTextColor, forKey: .placeholderTextColor) try container.encode(textAlignment, forKey: .textAlignment) - try container.encode(isEditable, forKey: .isEditable) + try container.encode(editable, forKey: .editable) } } From 95dc2e143f546540e84d6cdbe2da1878b87cae5d Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 12:58:18 -0400 Subject: [PATCH 22/25] additional check --- MVMCoreUI/BaseClasses/TextView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index 6d3a3d7f..e3702939 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -466,7 +466,7 @@ extension TextView: MoleculeViewProtocol { FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) - if model.selected ?? false { + if (model.selected ?? false) && !model.wasInitiallySelected { model.wasInitiallySelected = true DispatchQueue.main.async { self.becomeFirstResponder() From 3d50031f2a8bd7a3a63053123d6f6fd25b3075ce Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 13:06:20 -0400 Subject: [PATCH 23/25] enode --- MVMCoreUI/BaseClasses/TextViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseClasses/TextViewModel.swift b/MVMCoreUI/BaseClasses/TextViewModel.swift index 1972e60f..49ac664c 100644 --- a/MVMCoreUI/BaseClasses/TextViewModel.swift +++ b/MVMCoreUI/BaseClasses/TextViewModel.swift @@ -83,9 +83,9 @@ open class TextViewModel: TextEntryFieldModel { public override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) - try container.encodeIfPresent(fontStyle, forKey: .fontStyle) try container.encodeIfPresent(height, forKey: .height) - try container.encodeIfPresent(hideBorders, forKey: .hideBorders) + 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) From 61fdc30513b19feabc4e1612eb581a682e4b55da Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 13:33:03 -0400 Subject: [PATCH 24/25] using new toolbar --- MVMCoreUI/BaseClasses/TextView.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index e3702939..b16a2529 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -189,6 +189,7 @@ import UIKit smartQuotesType = .no smartDashesType = .no smartInsertDeleteType = .no + inputAccessoryView = nil font = textViewModel?.fontStyle.getFont() isEditable = true isOpaque = false @@ -198,6 +199,7 @@ import UIKit text = "" inputAccessoryView?.removeFromSuperview() + inputAccessoryView = nil initialConfiguration() } @@ -378,6 +380,11 @@ import UIKit text = textViewModel?.placeholder } + @objc func dismissFieldInput(_ sender: TextView) { + + resignFirstResponder() + } + //-------------------------------------------------- // MARK: - UITextViewDelegate //-------------------------------------------------- @@ -464,7 +471,8 @@ extension TextView: MoleculeViewProtocol { if isEditable { FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) - MVMCoreUICommonViewsUtility.addDismissToolbar(to: self, delegate: delegateObject?.uiTextViewDelegate) + inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: delegateObject?.uiTextViewDelegate, + action: #selector(dismissFieldInput)) if (model.selected ?? false) && !model.wasInitiallySelected { model.wasInitiallySelected = true From f7562986293a739abe8f37e7c34e82994cb8eb90 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 29 Apr 2020 13:42:52 -0400 Subject: [PATCH 25/25] delegateing --- MVMCoreUI/BaseClasses/TextView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseClasses/TextView.swift b/MVMCoreUI/BaseClasses/TextView.swift index b16a2529..191806bb 100644 --- a/MVMCoreUI/BaseClasses/TextView.swift +++ b/MVMCoreUI/BaseClasses/TextView.swift @@ -471,7 +471,8 @@ extension TextView: MoleculeViewProtocol { if isEditable { FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) - inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: delegateObject?.uiTextViewDelegate, + let observingDelegate = delegateObject?.uiTextViewDelegate ?? self + inputAccessoryView = UIToolbar.getToolbarWithDoneButton(delegate: observingDelegate, action: #selector(dismissFieldInput)) if (model.selected ?? false) && !model.wasInitiallySelected {