From 214a7e0a676a44c79ae4af1be0cb2b1a12fa37c4 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 11:53:44 -0500 Subject: [PATCH 01/12] caseiterable Signed-off-by: Matt Bruce --- VDS/Typography/VDSFontStyles.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/VDS/Typography/VDSFontStyles.swift b/VDS/Typography/VDSFontStyles.swift index f4f1daef..0851b97a 100644 --- a/VDS/Typography/VDSFontStyles.swift +++ b/VDS/Typography/VDSFontStyles.swift @@ -21,7 +21,7 @@ public enum VDSFontWeight: String, Codable { } } -public enum VDSTextPosition: String, Codable { +public enum VDSTextPosition: String, Codable, CaseIterable { case left, right, center var textAlignment: NSTextAlignment { @@ -36,7 +36,7 @@ public enum VDSTextPosition: String, Codable { } } -public enum VDSFontCategory: String, Codable { +public enum VDSFontCategory: String, Codable, CaseIterable { case feature case title case body @@ -52,7 +52,7 @@ public enum VDSFontCategory: String, Codable { } } -public enum VDSFontSize: String, Codable { +public enum VDSFontSize: String, Codable, CaseIterable { case xxlarge case xlarge case large @@ -72,7 +72,7 @@ public enum VDSFontSize: String, Codable { } } -public enum VDSFontStyle: String, Codable { +public enum VDSFontStyle: String, Codable, CaseIterable { public enum Error: Swift.Error { case fontNotFound } From ff61d3ff39a923ef98ad465a27d5c5bbe7a65188 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 11:53:58 -0500 Subject: [PATCH 02/12] updated for accessable Signed-off-by: Matt Bruce --- VDS/Protocols/Accessable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Protocols/Accessable.swift b/VDS/Protocols/Accessable.swift index 7fa273fc..67905b27 100644 --- a/VDS/Protocols/Accessable.swift +++ b/VDS/Protocols/Accessable.swift @@ -18,7 +18,7 @@ public protocol Accessable { } //Helpers to set within the UIControl -extension Modelable where Self: UIControl { +extension Modelable where Self: UIView { private var accessableModel: Accessable? { guard let model = self.model as? Accessable else { return nil From 2edd58c6d89cc08e6ad6990fa53e1da60e0fd5d6 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 11:54:27 -0500 Subject: [PATCH 03/12] updated for accessable and ensure label on showtext/textposition changes Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 39 ++++++++++++++++++--------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index 124b4917..34a6c275 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -20,7 +20,7 @@ import Combine @objcMembers open class VDSToggle: VDSControl, Modelable, Changable { public typealias ModelType = VDSToggleModel - @Published public var model: ModelType = DefaultToggleModel() + @Published open var model: ModelType = DefaultToggleModel() private var cancellable: AnyCancellable? //-------------------------------------------------- @@ -83,7 +83,13 @@ import Combine // MARK: - Computed Properties //-------------------------------------------------- @Proxy(\.model.showText) - public var showText: Bool + public var showText: Bool { + didSet { + if oldValue != showText { + ensureLabel() + } + } + } @Proxy(\.model.onText) public var onText: String @@ -92,7 +98,13 @@ import Combine public var offText: String @Proxy(\.model.textPosition) - public var textPosition: VDSTextPosition + public var textPosition: VDSTextPosition { + didSet { + if oldValue != textPosition { + ensureLabel() + } + } + } @Proxy(\.model.fontSize) public var fontSize: VDSFontSize @@ -103,9 +115,12 @@ import Combine @Proxy(\.model.surface) public var surface: Surface - @Proxy(\VDSToggle.model.on) + @Proxy(\.model.on) open var isOn: Bool + @Proxy(\.model.disabled) + open var disabled: Bool + open override var isEnabled: Bool { get { !model.disabled } set { @@ -132,7 +147,8 @@ import Combine // MARK: - Initializers //-------------------------------------------------- public required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") + super.init(coder: coder) + setup() } public override init(frame: CGRect) { @@ -179,10 +195,7 @@ import Combine super.setupView() isAccessibilityElement = true - setAccessibilityHint() - setAccessibilityLabel() accessibilityTraits = .button - addSubview(stackView) let toggleSize = Self.toggleSize @@ -317,9 +330,9 @@ import Combine /// Follow the SwiftUI View paradigm /// - Parameter viewModel: state - private func onStateChange(viewModel: ModelType) { + open func onStateChange(viewModel: ModelType) { let enabled = !viewModel.disabled - + label.set(with: viewModel) label.text = viewModel.on ? viewModel.onText : viewModel.offText @@ -367,9 +380,9 @@ import Combine backgroundColor = viewModel.surface == .dark ? VDSColor.backgroundPrimaryDark : .clear isUserInteractionEnabled = !viewModel.disabled - accessibilityHint = enabled ? viewModel.accessibilityHintEnabled :viewModel.accessibilityHintDisabled - accessibilityValue = viewModel.on ? viewModel.accessibilityValueEnabled : viewModel.accessibilityValueDisabled - accessibilityLabel = viewModel.on ? viewModel.accessibilityLabelEnabled : viewModel.accessibilityLabelDisabled + setAccessibilityHint(enabled) + setAccessibilityValue(viewModel.on) + setAccessibilityLabel(viewModel.on) setNeedsLayout() layoutIfNeeded() From 8dc988aae9fc5a9aa97772cfd0d92a21b8a644e9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 11:54:39 -0500 Subject: [PATCH 04/12] changed default from large to small Signed-off-by: Matt Bruce --- VDS/Components/Label/VDSLabelModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Components/Label/VDSLabelModel.swift b/VDS/Components/Label/VDSLabelModel.swift index 1958b84c..77520860 100644 --- a/VDS/Components/Label/VDSLabelModel.swift +++ b/VDS/Components/Label/VDSLabelModel.swift @@ -13,7 +13,7 @@ public protocol VDSLabelModel: Labelable, Surfaceable { open class DefaultLabelModel: VDSLabelModel { public var fontCategory: VDSFontCategory = .body - public var fontSize: VDSFontSize = .large + public var fontSize: VDSFontSize = .small public var fontWeight: VDSFontWeight = .regular public var textPosition: VDSTextPosition = .left public var surface: Surface = .light From b1253be64b6a27e87664f71d57bcc7582c154a6d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 11:54:49 -0500 Subject: [PATCH 05/12] implemented coder Signed-off-by: Matt Bruce --- VDS/Classes/VDSControl.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/Classes/VDSControl.swift b/VDS/Classes/VDSControl.swift index d60f4901..f0889fce 100644 --- a/VDS/Classes/VDSControl.swift +++ b/VDS/Classes/VDSControl.swift @@ -30,7 +30,7 @@ open class VDSControl: UIControl, ViewProtocol { public required init?(coder: NSCoder) { super.init(coder: coder) - fatalError("Control does not support xib.") + initialSetup() } //-------------------------------------------------- From 63d5b97de6a2ca8e1d0f2c86f4b06adb7ecfbfee Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 12:05:49 -0500 Subject: [PATCH 06/12] refactored color to surface Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 2 +- VDS/Protocols/Surfaceable.swift | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index 34a6c275..c569597f 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -377,7 +377,7 @@ import Combine }, completion: nil) } - backgroundColor = viewModel.surface == .dark ? VDSColor.backgroundPrimaryDark : .clear + backgroundColor = viewModel.surface.color isUserInteractionEnabled = !viewModel.disabled setAccessibilityHint(enabled) diff --git a/VDS/Protocols/Surfaceable.swift b/VDS/Protocols/Surfaceable.swift index 4988a146..c00fd04c 100644 --- a/VDS/Protocols/Surfaceable.swift +++ b/VDS/Protocols/Surfaceable.swift @@ -6,9 +6,14 @@ // import Foundation +import UIKit +import VDSColorTokens public enum Surface: String, Codable { case light, dark + public var color: UIColor { + return self == .dark ? VDSColor.backgroundPrimaryDark : .clear + } } public protocol Surfaceable { From 669c2b15b5f6d2fd0b50c5c16e0454d5d4838c35 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 12:41:05 -0500 Subject: [PATCH 07/12] refactored colors Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 66 +++++++++++++++++++-------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index c569597f..81c3defb 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -26,15 +26,46 @@ import Combine //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- - /// Holds the on and off colors for the container. - private var containerTintColor: (on: UIColor, off: UIColor) = (on: VDSColor.paletteGreen26, off: VDSColor.paletteGray44) + private var toggleTintColor: (on: UIColor, off: UIColor) { + return getToggleColor(for: disabled, surface: surface) + } - /// Holds the on and off colors for the knob. - private var knobTintColor: (on: UIColor, off: UIColor) = (on: VDSColor.paletteWhite, off: VDSColor.paletteWhite) + private var knobTintColor: (on: UIColor, off: UIColor) { + return getKnobColor(for: disabled, surface: surface) + } + + private func getToggleColor(for disabled: Bool, surface: Surface) -> (on: UIColor, off: UIColor) { + if disabled { + if surface == .light { + return (on: VDSColor.interactiveDisabledOnlight, off: VDSColor.interactiveDisabledOnlight) + } else { + return (on: VDSColor.interactiveDisabledOndark, off: VDSColor.interactiveDisabledOndark) + } + } else { + if surface == .light { + return (on: VDSColor.paletteGreen26, off: VDSColor.elementsSecondaryOndark) + } else { + return (on: VDSColor.paletteGreen34, off: VDSColor.paletteGray44) + } + } + } + + private func getKnobColor(for disabled: Bool, surface: Surface) -> (on: UIColor, off: UIColor) { + if disabled { + if surface == .light { + return (on: VDSColor.paletteGray95, off: VDSColor.paletteGray95) + } else { + return (on: VDSColor.paletteGray44, off: VDSColor.paletteGray44) + } + } else { + if surface == .light { + return (on: VDSColor.elementsPrimaryOndark, off: VDSColor.elementsPrimaryOndark) + } else { + return (on: VDSColor.elementsPrimaryOndark, off: VDSColor.elementsPrimaryOndark) + } + } + } - /// Holds the on and off colors for the disabled state.. - private var disabledTintColor: (container: UIColor, knob: UIColor) = (container: VDSColor.paletteGray11, knob: VDSColor.paletteWhite) - private var showTextSpacing: CGFloat { showText ? 12 : 0 } @@ -210,7 +241,7 @@ import Combine toggleView.layer.cornerRadius = toggleSize.height / 2.0 knobView.layer.cornerRadius = knobSize.height / 2.0 - toggleView.backgroundColor = containerTintColor.off + toggleView.backgroundColor = toggleTintColor.off toggleView.addSubview(knobView) @@ -251,7 +282,7 @@ import Combine public override func reset() { super.reset() - toggleView.backgroundColor = containerTintColor.off + toggleView.backgroundColor = toggleTintColor.off knobView.backgroundColor = knobTintColor.off setAccessibilityLabel() onChange = nil @@ -356,20 +387,17 @@ import Combine self.layoutIfNeeded() } + let toggleColor = getToggleColor(for: viewModel.disabled, surface: viewModel.surface) + let knobColor = getKnobColor(for: viewModel.disabled, surface: viewModel.surface) + if viewModel.disabled { - toggleView.backgroundColor = enabled ? viewModel.on ? containerTintColor.on : containerTintColor.off : disabledTintColor.container - knobView.backgroundColor = enabled ? viewModel.on ? knobTintColor.on : knobTintColor.off : disabledTintColor.knob + toggleView.backgroundColor = viewModel.on ? toggleColor.on : toggleColor.off + knobView.backgroundColor = viewModel.on ? knobColor.on : knobColor.off constrainKnob() } else { UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: { - if viewModel.on { - self.knobView.backgroundColor = self.knobTintColor.on - self.toggleView.backgroundColor = self.containerTintColor.on - - } else { - self.knobView.backgroundColor = self.knobTintColor.off - self.toggleView.backgroundColor = self.containerTintColor.off - } + self.toggleView.backgroundColor = viewModel.on ? toggleColor.on : toggleColor.off + self.knobView.backgroundColor = viewModel.on ? knobColor.on : knobColor.off }, completion: nil) UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [], animations: { From d7beea240c0d49f8ed53243f42334b5eb7ad551c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 13:31:41 -0500 Subject: [PATCH 08/12] upddate animations Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index 81c3defb..d23ddea4 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -328,22 +328,18 @@ import Combine } public override func touchesEnded(_ touches: Set, with event: UIEvent?) { - + print("touchesEnded") knobReformAnimation() - // Action only occurs of the user lifts up from withing acceptable region of the toggle. - guard let coordinates = touches.first?.location(in: self), - coordinates.x > -20, - coordinates.x < bounds.width + 20, - coordinates.y > -20, - coordinates.y < bounds.height + 20 - else { return } + let value = 20.0 + guard let coordinates = touches.first?.location(in: self) else { return } + guard coordinates.x > -value else { return } sendActions(for: .touchUpInside) } - public func touchesCancelled(_ touches: Set, with event: UIEvent) { - + open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { + print("touchesCancelled") knobReformAnimation() sendActions(for: .touchCancel) } @@ -400,7 +396,7 @@ import Combine self.knobView.backgroundColor = viewModel.on ? knobColor.on : knobColor.off }, completion: nil) - UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [], animations: { + UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: [], animations: { constrainKnob() }, completion: nil) } From 074700ddfed5f4584ca444b7cac7f230b93de5e9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 13:34:14 -0500 Subject: [PATCH 09/12] removed prints Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index d23ddea4..2dec377d 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -328,7 +328,6 @@ import Combine } public override func touchesEnded(_ touches: Set, with event: UIEvent?) { - print("touchesEnded") knobReformAnimation() // Action only occurs of the user lifts up from withing acceptable region of the toggle. let value = 20.0 @@ -339,7 +338,6 @@ import Combine } open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { - print("touchesCancelled") knobReformAnimation() sendActions(for: .touchCancel) } From 15c173d998c97aab5f6f9fc178bd83acf0ebf1cf Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 14:03:37 -0500 Subject: [PATCH 10/12] fixed font issue Signed-off-by: Matt Bruce --- VDS/Typography/FontProtocol.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/VDS/Typography/FontProtocol.swift b/VDS/Typography/FontProtocol.swift index 48b6bf43..9524f2a4 100644 --- a/VDS/Typography/FontProtocol.swift +++ b/VDS/Typography/FontProtocol.swift @@ -14,9 +14,8 @@ public protocol FontProtocol: CaseIterable, RawRepresentable, Hashable { } extension FontProtocol { - public func register() { - guard let bundle = Bundle(identifier: "com.verizon.vega.metrics") else { return } + guard let bundle = Bundle(identifier: "com.vzw.vds") else { return } Self.allCases.forEach{ font in if let url = bundle.url(forResource: font.fontName, withExtension: font.fontFileExtension){ do{ From 0ace568f7d26e19069e299b16a870eb798b947be Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 15:42:50 -0500 Subject: [PATCH 11/12] refactored label text Signed-off-by: Matt Bruce --- VDS/Components/Label/VDSLabel.swift | 18 +++++++++++++++++- VDS/Components/Label/VDSLabelModel.swift | 3 ++- VDS/Components/Toggle/VDSToggleModel.swift | 3 +-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/VDS/Components/Label/VDSLabel.swift b/VDS/Components/Label/VDSLabel.swift index acb6fc58..558ccb32 100644 --- a/VDS/Components/Label/VDSLabel.swift +++ b/VDS/Components/Label/VDSLabel.swift @@ -50,10 +50,26 @@ open class VDSLabel: UILabel, Modelable { } } + private func getTextColor(for disabled: Bool, surface: Surface) -> UIColor { + if disabled { + if surface == .light { + return VDSColor.elementsSecondaryOnlight + } else { + return VDSColor.elementsSecondaryOndark + } + } else { + if surface == .light { + return VDSColor.elementsPrimaryOnlight + } else { + return VDSColor.elementsPrimaryOndark + } + } + } + //functions private func onStateChange(viewModel: VDSLabelModel) { textAlignment = viewModel.textPosition.textAlignment - textColor = viewModel.surface == .dark ? VDSColor.elementsPrimaryOndark : VDSColor.elementsPrimaryOnlight + textColor = getTextColor(for: viewModel.disabled, surface: viewModel.surface) guard let vdsFont = try? VDSFontStyle.font(for: viewModel.fontCategory, fontWeight: viewModel.fontWeight, fontSize: viewModel.fontSize) else { font = VDSFontStyle.RegularBodyLarge.font diff --git a/VDS/Components/Label/VDSLabelModel.swift b/VDS/Components/Label/VDSLabelModel.swift index 77520860..721f87ea 100644 --- a/VDS/Components/Label/VDSLabelModel.swift +++ b/VDS/Components/Label/VDSLabelModel.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol VDSLabelModel: Labelable, Surfaceable { +public protocol VDSLabelModel: Labelable, Surfaceable, Disabling { } open class DefaultLabelModel: VDSLabelModel { @@ -17,5 +17,6 @@ open class DefaultLabelModel: VDSLabelModel { public var fontWeight: VDSFontWeight = .regular public var textPosition: VDSTextPosition = .left public var surface: Surface = .light + public var disabled: Bool = false required public init(){} } diff --git a/VDS/Components/Toggle/VDSToggleModel.swift b/VDS/Components/Toggle/VDSToggleModel.swift index 41c14372..475d40c6 100644 --- a/VDS/Components/Toggle/VDSToggleModel.swift +++ b/VDS/Components/Toggle/VDSToggleModel.swift @@ -14,7 +14,7 @@ extension VDSToggle { } } -public protocol VDSToggleModel: VDSLabelModel, FormFieldable, DataTrackable, Disabling, Accessable { +public protocol VDSToggleModel: VDSLabelModel, FormFieldable, DataTrackable, Accessable { var id: String? { get set } var showText: Bool { get set } var on: Bool { get set } @@ -32,7 +32,6 @@ extension VDSToggleModel { public class DefaultToggleModel: DefaultLabelModel, VDSToggleModel { public var id: String? public var inputId: String? - public var disabled: Bool = false public var showText: Bool = false public var on: Bool = false public var offText: String = "Off" From 70071778a1cdd75d3437e4f4be2c418bf387ad96 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 1 Aug 2022 16:24:25 -0500 Subject: [PATCH 12/12] updated colors Signed-off-by: Matt Bruce --- VDS/Components/Toggle/VDSToggle.swift | 6 +++--- VDS/Extensions/UIColor.swift | 25 ++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index 2dec377d..00f5a25e 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -37,13 +37,13 @@ import Combine private func getToggleColor(for disabled: Bool, surface: Surface) -> (on: UIColor, off: UIColor) { if disabled { if surface == .light { - return (on: VDSColor.interactiveDisabledOnlight, off: VDSColor.interactiveDisabledOnlight) + return (on: VDSColor.elementsDisabledOnlight, off: VDSColor.elementsDisabledOnlight) } else { - return (on: VDSColor.interactiveDisabledOndark, off: VDSColor.interactiveDisabledOndark) + return (on: VDSColor.elementsDisabledOnDark, off: VDSColor.elementsDisabledOnDark) } } else { if surface == .light { - return (on: VDSColor.paletteGreen26, off: VDSColor.elementsSecondaryOndark) + return (on: VDSColor.paletteGreen26, off: VDSColor.elementsSecondaryOnlight) } else { return (on: VDSColor.paletteGreen34, off: VDSColor.paletteGray44) } diff --git a/VDS/Extensions/UIColor.swift b/VDS/Extensions/UIColor.swift index 66142845..63c0cc57 100644 --- a/VDS/Extensions/UIColor.swift +++ b/VDS/Extensions/UIColor.swift @@ -7,6 +7,12 @@ import Foundation import UIKit +import VDSColorTokens + +extension VDSColor { + public static let elementsDisabledOnlight: UIColor = .init(hexString: "#D8DADA") + public static let elementsDisabledOnDark: UIColor = .init(hexString: "#333333") +} extension UIColor { //-------------------------------------------------- @@ -143,5 +149,22 @@ extension UIColor { return nil } - + + public convenience init(hexString: String) { + let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) + var int = UInt64() + Scanner(string: hex).scanHexInt64(&int) + let a, r, g, b: UInt64 + switch hex.count { + case 3: // RGB (12-bit) + (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) + case 6: // RGB (24-bit) + (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) + case 8: // ARGB (32-bit) + (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + default: + (a, r, g, b) = (255, 0, 0, 0) + } + self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) + } }