Merge branch 'develop' into feature/groups
# Conflicts: # VDS.xcodeproj/project.pbxproj Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
commit
63d8ad2d25
@ -64,7 +64,7 @@
|
||||
EAF7F11828A1475A00B287F5 /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */; };
|
||||
EAF7F12C28A1617600B287F5 /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F12B28A1617600B287F5 /* SelectorBase.swift */; };
|
||||
EAF7F12F28A1619600B287F5 /* SelectorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F12E28A1619600B287F5 /* SelectorModel.swift */; };
|
||||
EAF7F13128A17FAB00B287F5 /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F13028A17FAB00B287F5 /* RadioButtonGroup.swift */; };
|
||||
EAF7F13328A2A16500B287F5 /* LabelAttributeAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -140,6 +140,7 @@
|
||||
EAF7F11628A1475A00B287F5 /* RadioButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = "<group>"; };
|
||||
EAF7F12B28A1617600B287F5 /* SelectorBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = "<group>"; };
|
||||
EAF7F12E28A1619600B287F5 /* SelectorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorModel.swift; sourceTree = "<group>"; };
|
||||
EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeAttachment.swift; sourceTree = "<group>"; };
|
||||
EAF7F13028A17FAB00B287F5 /* RadioButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -271,9 +272,9 @@
|
||||
EA3362442892F9130071C351 /* Labelable.swift */,
|
||||
EAF7F0BA289D80ED00B287F5 /* Modelable.swift */,
|
||||
EA3361BE288B2EA60071C351 /* ModelHandlerable.swift */,
|
||||
EAF7F0A5289B0CE000B287F5 /* Resetable.swift */,
|
||||
EA3361C8289054C50071C351 /* Surfaceable.swift */,
|
||||
EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */,
|
||||
EAF7F0A5289B0CE000B287F5 /* Resetable.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
@ -350,11 +351,12 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EAF7F0A3289B017C00B287F5 /* LabelAttributeModel.swift */,
|
||||
EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */,
|
||||
EAF7F13228A2A16500B287F5 /* LabelAttributeAttachment.swift */,
|
||||
EAF7F0B0289B177F00B287F5 /* LabelAttributeColor.swift */,
|
||||
EAF7F0AA289B13FD00B287F5 /* LabelAttributeFont.swift */,
|
||||
EAF7F0AC289B142900B287F5 /* LabelAttributeStrikeThrough.swift */,
|
||||
EAF7F0AE289B144C00B287F5 /* LabelAttributeUnderline.swift */,
|
||||
EAF7F0B0289B177F00B287F5 /* LabelAttributeColor.swift */,
|
||||
EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */,
|
||||
);
|
||||
path = Attributes;
|
||||
sourceTree = "<group>";
|
||||
@ -514,6 +516,7 @@
|
||||
EA33624728931B050071C351 /* Initable.swift in Sources */,
|
||||
EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */,
|
||||
EAF7F0B1289B177F00B287F5 /* LabelAttributeColor.swift in Sources */,
|
||||
EAF7F13328A2A16500B287F5 /* LabelAttributeAttachment.swift in Sources */,
|
||||
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */,
|
||||
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
|
||||
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
||||
|
||||
@ -19,8 +19,12 @@ open class Control<ModelType: Modelable>: UIControl, ModelHandlerable, ViewProto
|
||||
self.model = model
|
||||
}
|
||||
|
||||
open func onStateChange(viewModel: ModelType) {
|
||||
|
||||
open func shouldUpdateView(viewModel: ModelType) -> Bool {
|
||||
fatalError("Implement shouldUpdateView")
|
||||
}
|
||||
|
||||
open func updateView(viewModel: ModelType) {
|
||||
fatalError("Implement updateView")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -58,8 +62,14 @@ open class Control<ModelType: Modelable>: UIControl, ModelHandlerable, ViewProto
|
||||
public func initialSetup() {
|
||||
if !initialSetupPerformed {
|
||||
initialSetupPerformed = true
|
||||
cancellable = $model.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
self?.onStateChange(viewModel: viewModel)
|
||||
//setup viewUpdate
|
||||
cancellable = $model.filter { viewModel in
|
||||
return self.shouldUpdateView(viewModel: viewModel)
|
||||
|
||||
}.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
guard let self = self else { return }
|
||||
self.updateView(viewModel: viewModel)
|
||||
|
||||
}
|
||||
setup()
|
||||
}
|
||||
|
||||
@ -14,15 +14,19 @@ open class View<ModelType: Modelable>: UIView, ModelHandlerable, ViewProtocol, R
|
||||
|
||||
@Published public var model: ModelType
|
||||
private var cancellable: AnyCancellable?
|
||||
|
||||
|
||||
open func set(with model: ModelType) {
|
||||
self.model = model
|
||||
}
|
||||
|
||||
open func onStateChange(viewModel: ModelType) {
|
||||
|
||||
open func shouldUpdateView(viewModel: ModelType) -> Bool {
|
||||
fatalError("Implement shouldUpdateView")
|
||||
}
|
||||
|
||||
open func updateView(viewModel: ModelType) {
|
||||
fatalError("Implement updateView")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -57,8 +61,14 @@ open class View<ModelType: Modelable>: UIView, ModelHandlerable, ViewProtocol, R
|
||||
public func initialSetup() {
|
||||
if !initialSetupPerformed {
|
||||
initialSetupPerformed = true
|
||||
cancellable = $model.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
self?.onStateChange(viewModel: viewModel)
|
||||
//setup viewUpdate
|
||||
cancellable = $model.filter { viewModel in
|
||||
return self.shouldUpdateView(viewModel: viewModel)
|
||||
|
||||
}.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
guard let self = self else { return }
|
||||
self.updateView(viewModel: viewModel)
|
||||
|
||||
}
|
||||
setup()
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
//
|
||||
// LabelAttributeAttachment.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Matt Bruce on 8/9/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public protocol LabelAttributeAttachment: LabelAttributeModel {
|
||||
func getAttachment() throws -> NSTextAttachment
|
||||
}
|
||||
|
||||
extension LabelAttributeAttachment {
|
||||
public func setAttribute(on attributedString: NSMutableAttributedString) {
|
||||
do {
|
||||
let mutableString = NSMutableAttributedString()
|
||||
let attachment = try getAttachment()
|
||||
mutableString.append(NSAttributedString(attachment: attachment))
|
||||
attributedString.insert(mutableString, at: location)
|
||||
} catch {
|
||||
//TODO: Error Handling
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,8 +94,15 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
accessibilityCustomActions = []
|
||||
accessibilityTraits = .staticText
|
||||
cancellable = $model.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
self?.onStateChange(viewModel: viewModel)
|
||||
|
||||
//setup viewUpdate
|
||||
cancellable = $model.filter { viewModel in
|
||||
return self.shouldUpdateView(viewModel: viewModel)
|
||||
|
||||
}.debounce(for: .seconds(Constants.ModelStateDebounce), scheduler: RunLoop.main).sink { [weak self] viewModel in
|
||||
guard let self = self else { return }
|
||||
self.updateView(viewModel: viewModel)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,7 +127,15 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
||||
//--------------------------------------------------
|
||||
/// Follow the SwiftUI View paradigm
|
||||
/// - Parameter viewModel: state
|
||||
open func onStateChange(viewModel: ModelType) {
|
||||
open func shouldUpdateView(viewModel: ModelType) -> Bool {
|
||||
return viewModel.text != model.text
|
||||
|| viewModel.disabled != model.disabled
|
||||
|| viewModel.surface != model.surface
|
||||
|| viewModel.font != model.font
|
||||
|| viewModel.textPosition != model.textPosition
|
||||
}
|
||||
|
||||
open func updateView(viewModel: ModelType) {
|
||||
textAlignment = viewModel.textPosition.textAlignment
|
||||
textColor = textColorConfiguration.getColor(viewModel)
|
||||
|
||||
@ -146,7 +161,7 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
|
||||
attribute.setAttribute(on: mutableText)
|
||||
|
||||
//see if the attribute is Actionable
|
||||
if let actionable = attribute as? LabelAttributeActionable{
|
||||
if let actionable = attribute as? any LabelAttributeActionable{
|
||||
//create a accessibleAction
|
||||
let customAccessibilityAction = customAccessibilityAction(range: actionable.range)
|
||||
|
||||
|
||||
@ -300,7 +300,11 @@ open class SelectorBase<ModelType: SelectorModel>: Control<ModelType>, Changable
|
||||
//--------------------------------------------------
|
||||
/// Follow the SwiftUI View paradigm
|
||||
/// - Parameter viewModel: state
|
||||
open override func onStateChange(viewModel: ModelType) {
|
||||
open override func shouldUpdateView(viewModel: ModelType) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open override func updateView(viewModel: ModelType) {
|
||||
let enabled = !viewModel.disabled
|
||||
|
||||
updateLabels(viewModel)
|
||||
|
||||
@ -384,7 +384,11 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
|
||||
//--------------------------------------------------
|
||||
/// Follow the SwiftUI View paradigm
|
||||
/// - Parameter viewModel: state
|
||||
open override func onStateChange(viewModel: ModelType) {
|
||||
open override func shouldUpdateView(viewModel: ModelType) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open override func updateView(viewModel: ModelType) {
|
||||
label.set(with: viewModel.label)
|
||||
updateLabel(viewModel)
|
||||
updateToggle(viewModel)
|
||||
|
||||
@ -6,10 +6,13 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol ModelHandlerable {
|
||||
associatedtype ModelType: Modelable
|
||||
var model: ModelType { get set }
|
||||
|
||||
init(with model: ModelType)
|
||||
func set(with model: ModelType)
|
||||
func shouldUpdateView(viewModel: ModelType) -> Bool
|
||||
func updateView(viewModel: ModelType)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user