refactored color configurations and refactored classes

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-08-05 10:49:02 -05:00
parent 4c38676f59
commit b253bf3e03
8 changed files with 224 additions and 142 deletions

View File

@ -57,7 +57,7 @@
EAF7F0B3289B1ADC00B287F5 /* LabelAttributeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */; };
EAF7F0B5289C126F00B287F5 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B4289C126F00B287F5 /* UILabel.swift */; };
EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */; };
EAF7F0B9289C139800B287F5 /* ModelColorHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B8289C139800B287F5 /* ModelColorHelpers.swift */; };
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -122,7 +122,7 @@
EAF7F0B2289B1ADC00B287F5 /* LabelAttributeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeAction.swift; sourceTree = "<group>"; };
EAF7F0B4289C126F00B287F5 /* UILabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
EAF7F0B6289C12A600B287F5 /* UITapGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITapGestureRecognizer.swift; sourceTree = "<group>"; };
EAF7F0B8289C139800B287F5 /* ModelColorHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelColorHelpers.swift; sourceTree = "<group>"; };
EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorConfiguration.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -256,9 +256,9 @@
isa = PBXGroup;
children = (
EA3C3B4B2894823E000CA526 /* AnyProxy-PropertyWrapper.swift */,
EAF7F0B8289C139800B287F5 /* ColorConfiguration.swift */,
EAF7F09D289AAEC000B287F5 /* Constants.swift */,
EA3361B5288B2A410071C351 /* Control.swift */,
EAF7F0B8289C139800B287F5 /* ModelColorHelpers.swift */,
EAF7F09F289AB7EC00B287F5 /* View.swift */,
);
path = Classes;
@ -464,7 +464,7 @@
EA33624728931B050071C351 /* Initable.swift in Sources */,
EAF7F0A4289B017C00B287F5 /* LabelAttributeModel.swift in Sources */,
EAF7F0B1289B177F00B287F5 /* LabelAttributeColor.swift in Sources */,
EAF7F0B9289C139800B287F5 /* ModelColorHelpers.swift in Sources */,
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */,
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,

View File

@ -0,0 +1,131 @@
//
// ModelColorConfiguration.swift
// VDS
//
// Created by Matt Bruce on 8/4/22.
//
import Foundation
import UIKit
public protocol Colorable {
associatedtype ModelType
func getColor(_ viewModel: ModelType) -> UIColor
}
public protocol BinaryColorable{
var userTrueColor: Bool { get }
}
/// Meant to be used in a Object that implements the following interfaces for 2 possible color combinations
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .light
///
/// let config = SurfaceColorConfiguration<TestModel>()
///
/// config.lightColor = .black
/// config.darkColor = .white
///
/// let textColor = config.getColor(model) //returns .black
open class SurfaceColorConfiguration<ModelType:Surfaceable>: Colorable {
public var lightColor: UIColor = .clear
public var darkColor: UIColor = .clear
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.surface == .light ? lightColor : darkColor
}
}
/// Meant to be used in a Object that implements the following interfaces for 4 possible color combinations
/// - Disabling (var disabled: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .dark
/// model.disabled = false
///
/// let config = DisabledSurfaceColorConfiguration<TestModel>()
///
/// //disabled == false
/// config.enabled.lightColor = .black
/// config.enabled.darkColor = .white
///
/// //disabled == true
/// config.disabled.lightColor = .gray
/// config.disabled.darkColor = .lightGray
///
/// let textColor = config.getColor(model) //returns .white
///
///
open class DisabledSurfaceColorConfiguration<ModelType:Disabling & Surfaceable>: Colorable {
public var disabled = SurfaceColorConfiguration<ModelType>()
public var enabled = SurfaceColorConfiguration<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.disabled ? disabled.getColor(viewModel) : enabled.getColor(viewModel)
}
}
/// Meant to be used in a Object that implements the following interfaces for 4 possible color combinations
/// - BinaryColorable (var userTrueColor: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.surface = .dark
/// model.on = true //this is read in the extension var userTrueColor
/// let config = BinarySurfaceColorConfiguration<TestModel>()
///
/// //True from BinaryColorable.userTrueColor
/// config.isTrue.lightColor = .black
/// config.isTrue.darkColor = .white
///
/// //False from BinaryColorable.userTrueColor
/// config.isFalse.lightColor = .red
/// config.isFalse.darkColor = .red
///
/// let textColor = config.getColor(model) //returns .white
///
///
open class BinarySurfaceColorConfiguration<ModelType:Surfaceable & BinaryColorable>: Colorable{
public var isTrue = SurfaceColorConfiguration<ModelType>()
public var isFalse = SurfaceColorConfiguration<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.userTrueColor ? isTrue.getColor(viewModel) : isFalse.getColor(viewModel)
}
}
/// Meant to be used in a Object that implements the following interfaces for 8 possible color combinations
/// - BinaryColorable (var userTrueColor: Bool)
/// - Disabling (var disabled: Bool)
/// - Surfaceable (var surface: Surface)
///
/// let model = TestModel()
/// model.
/// let config = BinaryDisabledSurfaceColorConfiguration<TestModel>()
///
/// //True
/// config.isTrue.enabled.lightColor = .black
/// config.isTrue.enabled.darkColor = .white
/// config.isTrue.disabled.lightColor = .darkGray
/// config.isTrue.disabled.darkColor = .lightGray
///
/// //False
/// config.isFalse.enabled.lightColor = .red
/// config.isFalse.enabled.darkColor = .red
/// config.isFalse.disabled.lightColor =.darkGray
/// config.isFalse.disabled.darkColor = .lightGray
///
/// let textColor = config.getColor(model)
///
///
open class BinaryDisabledSurfaceColorConfiguration<ModelType:Disabling & Surfaceable & BinaryColorable>: Colorable {
public var isTrue = DisabledSurfaceColorConfiguration<ModelType>()
public var isFalse = DisabledSurfaceColorConfiguration<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.userTrueColor ? isTrue.getColor(viewModel) : isFalse.getColor(viewModel)
}
}

View File

@ -1,68 +0,0 @@
//
// ModelColorHelper.swift
// VDS
//
// Created by Matt Bruce on 8/4/22.
//
import Foundation
import UIKit
public protocol Colorable {
associatedtype ModelType
func getColor(_ viewModel: ModelType) -> UIColor
}
open class ModelSurfaceColorHelper<ModelType:Surfaceable>: Colorable {
public var lightColor: UIColor = .clear
public var darkColor: UIColor = .clear
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.surface == .light ? lightColor : darkColor
}
}
open class ModelSingleColorHelper<ModelType:Disabling & Surfaceable>: Colorable {
public var disabled = ModelSurfaceColorHelper<ModelType>()
public var enabled = ModelSurfaceColorHelper<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.disabled ? disabled.getColor(viewModel) : enabled.getColor(viewModel)
}
}
public protocol BinaryColorable{
var userTrueColor: Bool { get }
}
open class BinaryColorHelper<ModelType:BinaryColorable> {
public var trueColor: UIColor = .clear
public var falseColor: UIColor = .clear
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.userTrueColor ? trueColor : falseColor
}
}
open class BinarySurfaceColorHelper<ModelType:Surfaceable & BinaryColorable>: Colorable{
public var light = BinaryColorHelper<ModelType>()
public var dark = BinaryColorHelper<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
if viewModel.surface == .light {
return light.getColor(viewModel)
} else {
return dark.getColor(viewModel)
}
}
}
open class BinaryModelColorHelper<ModelType:Disabling & Surfaceable & BinaryColorable>: Colorable {
public var disabled = BinarySurfaceColorHelper<ModelType>()
public var enabled = BinarySurfaceColorHelper<ModelType>()
public func getColor(_ viewModel: ModelType) -> UIColor {
return viewModel.disabled ? disabled.getColor(viewModel) : enabled.getColor(viewModel)
}
}

View File

@ -271,48 +271,48 @@ open class CheckboxBase<ModelType: CheckboxModel>: Control<ModelType>, Changable
/// Manages the appearance of the checkbox.
private var shapeLayer: CAShapeLayer?
private var checkboxBackgroundColor: CheckboxErrorColorHelper = {
let helper = CheckboxErrorColorHelper()
helper.disabled.light.trueColor = VDSColor.interactiveDisabledOnlight
helper.disabled.dark.trueColor = VDSColor.interactiveDisabledOndark
helper.error.light.trueColor = VDSColor.elementsPrimaryOnlight
helper.error.light.falseColor = VDSColor.feedbackErrorBackgroundOnlight
helper.error.dark.trueColor = VDSColor.elementsPrimaryOndark
helper.error.dark.falseColor = VDSColor.feedbackErrorBackgroundOndark
helper.enabled.light.trueColor = VDSColor.elementsPrimaryOnlight
helper.enabled.dark.trueColor = VDSColor.elementsPrimaryOndark
return helper
private var checkboxBackgroundColorConfiguration: CheckboxErrorColorConfiguration = {
let config = CheckboxErrorColorConfiguration()
config.isTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
config.isTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.isTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
config.isTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
config.error.isTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
config.error.isTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.error.isFalse.enabled.lightColor = VDSColor.feedbackErrorBackgroundOnlight
config.error.isFalse.enabled.darkColor = VDSColor.feedbackErrorBackgroundOndark
return config
}()
private var checkboxBorderColor: CheckboxErrorColorHelper = {
let helper = CheckboxErrorColorHelper()
helper.disabled.light.trueColor = VDSColor.interactiveDisabledOnlight
helper.disabled.light.falseColor = VDSColor.interactiveDisabledOnlight
helper.disabled.dark.trueColor = VDSColor.interactiveDisabledOndark
helper.disabled.dark.falseColor = VDSColor.interactiveDisabledOndark
helper.error.light.trueColor = VDSColor.elementsPrimaryOnlight
helper.error.light.falseColor = VDSColor.feedbackErrorOnlight
helper.error.dark.trueColor = VDSColor.elementsPrimaryOndark
helper.error.dark.falseColor = VDSColor.feedbackErrorOndark
helper.enabled.light.trueColor = VDSColor.elementsPrimaryOnlight
helper.enabled.light.falseColor = VDSFormControlsColor.borderOnlight
helper.enabled.dark.trueColor = VDSColor.elementsPrimaryOndark
helper.enabled.dark.falseColor = VDSFormControlsColor.borderOndark
return helper
private var checkboxBorderColorConfiguration: CheckboxErrorColorConfiguration = {
let config = CheckboxErrorColorConfiguration()
config.isTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
config.isTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.isFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight
config.isFalse.enabled.darkColor = VDSFormControlsColor.borderOndark
config.isTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
config.isTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
config.isFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
config.isFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
config.error.isTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight
config.error.isTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.error.isFalse.enabled.lightColor = VDSColor.feedbackErrorOnlight
config.error.isFalse.enabled.darkColor = VDSColor.feedbackErrorOndark
return config
}()
private var checkboxCheckColor: BinarySurfaceColorHelper<ModelType> = {
let helper = BinarySurfaceColorHelper<ModelType>()
helper.light.trueColor = VDSColor.elementsPrimaryOndark
helper.dark.trueColor = VDSColor.elementsPrimaryOnlight
return helper
private var checkboxCheckColorConfiguration: BinarySurfaceColorConfiguration<ModelType> = {
let config = BinarySurfaceColorConfiguration<ModelType>()
config.isTrue.lightColor = VDSColor.elementsPrimaryOndark
config.isTrue.darkColor = VDSColor.elementsPrimaryOnlight
return config
}()
private func updateCheckbox(_ viewModel: ModelType) {
//get the colors
let backgroundColor = checkboxBackgroundColor.getColor(viewModel)
let borderColor = checkboxBorderColor.getColor(viewModel)
let checkColor = checkboxCheckColor.getColor(viewModel)
let backgroundColor = checkboxBackgroundColorConfiguration.getColor(viewModel)
let borderColor = checkboxBorderColorConfiguration.getColor(viewModel)
let checkColor = checkboxCheckColorConfiguration.getColor(viewModel)
if let shapeLayer = shapeLayer, let sublayers = layer.sublayers, sublayers.contains(shapeLayer) {
shapeLayer.removeFromSuperlayer()
@ -413,10 +413,10 @@ open class CheckboxBase<ModelType: CheckboxModel>: Control<ModelType>, Changable
}
//--------------------------------------------------
// MARK: - Color Class Helpers
// MARK: - Color Class Configurations
//--------------------------------------------------
private class CheckboxErrorColorHelper: BinaryModelColorHelper<ModelType> {
public let error = BinarySurfaceColorHelper<ModelType>()
private class CheckboxErrorColorConfiguration: BinaryDisabledSurfaceColorConfiguration<ModelType> {
public let error = BinaryDisabledSurfaceColorConfiguration<ModelType>()
override func getColor(_ viewModel: ModelType) -> UIColor {
//only show error is enabled and showError == true

View File

@ -117,9 +117,9 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
/// - Parameter viewModel: state
open func onStateChange(viewModel: ModelType) {
textAlignment = viewModel.textPosition.textAlignment
textColor = textColorHelper.getColor(viewModel)
textColor = textColorConfiguration.getColor(viewModel)
if let vdsFont = self.font {
if let vdsFont = viewModel.font {
font = vdsFont
} else {
font = FontStyle.defaultStyle.font
@ -163,8 +163,8 @@ open class LabelBase<ModelType: LabelModel>: UILabel, ModelHandlerable, Initable
//--------------------------------------------------
// MARK: - Private Functions
//--------------------------------------------------
private var textColorHelper: ModelSingleColorHelper<ModelType> = {
let helper = ModelSingleColorHelper<ModelType>()
private var textColorConfiguration: DisabledSurfaceColorConfiguration<ModelType> = {
let helper = DisabledSurfaceColorConfiguration<ModelType>()
helper.disabled.lightColor = VDSColor.elementsSecondaryOnlight
helper.disabled.darkColor = VDSColor.elementsSecondaryOndark
helper.enabled.lightColor = VDSColor.elementsPrimaryOnlight

View File

@ -179,31 +179,30 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
//--------------------------------------------------
// MARK: - Toggle
//--------------------------------------------------
private var toggleColor: BinaryModelColorHelper<ModelType> = {
let helper = BinaryModelColorHelper<ModelType>()
helper.disabled.light.trueColor = VDSColor.interactiveDisabledOnlight
helper.disabled.light.falseColor = VDSColor.interactiveDisabledOnlight
helper.disabled.dark.trueColor = VDSColor.interactiveDisabledOndark
helper.disabled.dark.falseColor = VDSColor.interactiveDisabledOndark
helper.enabled.light.trueColor = VDSColor.paletteGreen26
helper.enabled.light.falseColor = VDSColor.elementsSecondaryOnlight
helper.enabled.dark.trueColor = VDSColor.paletteGreen34
helper.enabled.dark.falseColor = VDSColor.paletteGray44
return helper
private var toggleColorConfiguration: BinaryDisabledSurfaceColorConfiguration<ModelType> = {
let config = BinaryDisabledSurfaceColorConfiguration<ModelType>()
config.isTrue.enabled.lightColor = VDSColor.paletteGreen26
config.isTrue.enabled.darkColor = VDSColor.paletteGreen34
config.isTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight
config.isTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark
config.isFalse.enabled.lightColor = VDSColor.elementsSecondaryOnlight
config.isFalse.enabled.darkColor = VDSColor.paletteGray44
config.isFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight
config.isFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark
return config
} ()
private var knobColor: BinaryModelColorHelper<ModelType> = {
let helper = BinaryModelColorHelper<ModelType>()
helper.disabled.light.trueColor = VDSColor.paletteGray95
helper.disabled.light.falseColor = VDSColor.paletteGray95
helper.disabled.dark.trueColor = VDSColor.paletteGray44
helper.disabled.dark.falseColor = VDSColor.paletteGray44
helper.enabled.light.trueColor = VDSColor.elementsPrimaryOndark
helper.enabled.light.falseColor = VDSColor.elementsPrimaryOndark
helper.enabled.dark.trueColor = VDSColor.elementsPrimaryOndark
helper.enabled.dark.falseColor = VDSColor.elementsPrimaryOndark
return helper
private var knobColorConfiguration: BinaryDisabledSurfaceColorConfiguration<ModelType> = {
let config = BinaryDisabledSurfaceColorConfiguration<ModelType>()
config.isTrue.enabled.lightColor = VDSColor.elementsPrimaryOndark
config.isTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.isTrue.disabled.lightColor = VDSColor.paletteGray95
config.isTrue.disabled.darkColor = VDSColor.paletteGray44
config.isFalse.enabled.lightColor = VDSColor.elementsPrimaryOndark
config.isFalse.enabled.darkColor = VDSColor.elementsPrimaryOndark
config.isFalse.disabled.lightColor = VDSColor.paletteGray95
config.isFalse.disabled.darkColor = VDSColor.paletteGray44
return config
} ()
private func updateToggle(_ viewModel: ModelType) {
@ -224,8 +223,8 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
self.layoutIfNeeded()
}
let toggleColor = toggleColor.getColor(viewModel)
let knobColor = knobColor.getColor(viewModel)
let toggleColor = toggleColorConfiguration.getColor(viewModel)
let knobColor = knobColorConfiguration.getColor(viewModel)
if viewModel.disabled {
toggleView.backgroundColor = toggleColor
@ -282,7 +281,7 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
toggleView.layer.cornerRadius = toggleSize.height / 2.0
knobView.layer.cornerRadius = knobSize.height / 2.0
toggleView.backgroundColor = toggleColor.getColor(model)
toggleView.backgroundColor = toggleColorConfiguration.getColor(model)
toggleView.addSubview(knobView)
@ -305,8 +304,8 @@ open class ToggleBase<ModelType: ToggleModel>: Control<ModelType>, Changable {
public override func reset() {
super.reset()
toggleView.backgroundColor = toggleColor.getColor(model)
knobView.backgroundColor = knobColor.getColor(model)
toggleView.backgroundColor = toggleColorConfiguration.getColor(model)
knobView.backgroundColor = knobColorConfiguration.getColor(model)
setAccessibilityLabel()
onChange = nil
}

View File

@ -163,3 +163,23 @@ extension UIColor {
self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
}
}
extension UIColor {
convenience init(
light lightModeColor: @escaping @autoclosure () -> UIColor,
dark darkModeColor: @escaping @autoclosure () -> UIColor
) {
self.init { traitCollection in
switch traitCollection.userInterfaceStyle {
case .light:
return lightModeColor()
case .dark:
return darkModeColor()
case .unspecified:
return lightModeColor()
@unknown default:
return lightModeColor()
}
}
}
}

View File

@ -17,7 +17,7 @@ public protocol Accessable {
var accessibilityLabelDisabled: String? { get set }
}
//Helpers to set within the UIControl
//Configurations to set within the UIControl
extension ModelHandlerable where Self: UIView {
private var accessableModel: Accessable? {
guard let model = self.model as? Accessable else {