From b1324444f8157d143be70c5da4cd748e56575344 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 26 Jul 2022 11:08:42 -0500 Subject: [PATCH] refactored out speicific atomic code Signed-off-by: Matt Bruce --- VDS.xcodeproj/project.pbxproj | 16 +-- VDS/BaseClasses/Control.swift | 14 +-- .../Toggle/ToggleModelProtocol.swift | 2 +- VDS/Components/Toggle/VDSToggle.swift | 97 ++++++++----------- VDS/Protocols/Accessable.swift | 52 ++++++++++ VDS/Utilities/VDSHelper.swift | 14 --- 6 files changed, 107 insertions(+), 88 deletions(-) create mode 100644 VDS/Protocols/Accessable.swift delete mode 100644 VDS/Utilities/VDSHelper.swift diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 4c13c71a..d450dc75 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ EA33617D288B19210071C351 /* VDS.h in Headers */ = {isa = PBXBuildFile; fileRef = EA33616F288B19200071C351 /* VDS.h */; settings = {ATTRIBUTES = (Public, ); }; }; EA336195288B1C420071C351 /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA33618E288B1C0C0071C351 /* VDSColorTokens.xcframework */; }; EA336197288B1C420071C351 /* VDSFormControlsTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA33618F288B1C0C0071C351 /* VDSFormControlsTokens.xcframework */; }; - EA33619F288B1E4D0071C351 /* VDSToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33619E288B1E4D0071C351 /* VDSToggle.swift */; }; EA3361A2288B1E840071C351 /* ToggleModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361A1288B1E840071C351 /* ToggleModelProtocol.swift */; }; EA3361A8288B23300071C351 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361A7288B23300071C351 /* UIColor.swift */; }; EA3361AA288B25E40071C351 /* Disabling.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361A9288B25E40071C351 /* Disabling.swift */; }; @@ -23,9 +22,10 @@ EA3361B3288B265D0071C351 /* Changable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361B2288B265D0071C351 /* Changable.swift */; }; EA3361B6288B2A410071C351 /* Control.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361B5288B2A410071C351 /* Control.swift */; }; EA3361B8288B2AAA0071C351 /* ViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */; }; - EA3361BB288B2C010071C351 /* VDSHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361BA288B2C010071C351 /* VDSHelper.swift */; }; EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361BC288B2C760071C351 /* TypeAlias.swift */; }; EA3361BF288B2EA60071C351 /* Modelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361BE288B2EA60071C351 /* Modelable.swift */; }; + EA3361C328902D960071C351 /* VDSToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361C228902D960071C351 /* VDSToggle.swift */; }; + EA3361C5289030FC0071C351 /* Accessable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361C4289030FC0071C351 /* Accessable.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -46,7 +46,6 @@ EA33617B288B19210071C351 /* VDSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSTests.swift; sourceTree = ""; }; EA33618E288B1C0C0071C351 /* VDSColorTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSColorTokens.xcframework; path = "/Users/mattbruce/Documents/Projects/iPhone/Frameworks/MVA-JSONCreator/JSONCreator_iOS/../SharedFrameworks/VDSColorTokens.xcframework"; sourceTree = ""; }; EA33618F288B1C0C0071C351 /* VDSFormControlsTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSFormControlsTokens.xcframework; path = "/Users/mattbruce/Documents/Projects/iPhone/Frameworks/MVA-JSONCreator/JSONCreator_iOS/../SharedFrameworks/VDSFormControlsTokens.xcframework"; sourceTree = ""; }; - EA33619E288B1E4D0071C351 /* VDSToggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSToggle.swift; sourceTree = ""; }; EA3361A1288B1E840071C351 /* ToggleModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleModelProtocol.swift; sourceTree = ""; }; EA3361A7288B23300071C351 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; }; EA3361A9288B25E40071C351 /* Disabling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disabling.swift; sourceTree = ""; }; @@ -56,9 +55,10 @@ EA3361B2288B265D0071C351 /* Changable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Changable.swift; sourceTree = ""; }; EA3361B5288B2A410071C351 /* Control.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Control.swift; sourceTree = ""; }; EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewProtocol.swift; sourceTree = ""; }; - EA3361BA288B2C010071C351 /* VDSHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSHelper.swift; sourceTree = ""; }; EA3361BC288B2C760071C351 /* TypeAlias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = ""; }; EA3361BE288B2EA60071C351 /* Modelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modelable.swift; sourceTree = ""; }; + EA3361C228902D960071C351 /* VDSToggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSToggle.swift; sourceTree = ""; }; + EA3361C4289030FC0071C351 /* Accessable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Accessable.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -143,7 +143,7 @@ EA3361A0288B1E6F0071C351 /* Toggle */ = { isa = PBXGroup; children = ( - EA33619E288B1E4D0071C351 /* VDSToggle.swift */, + EA3361C228902D960071C351 /* VDSToggle.swift */, EA3361A1288B1E840071C351 /* ToggleModelProtocol.swift */, ); path = Toggle; @@ -167,6 +167,7 @@ EA3361B0288B26490071C351 /* Invertable.swift */, EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */, EA3361BE288B2EA60071C351 /* Modelable.swift */, + EA3361C4289030FC0071C351 /* Accessable.swift */, ); path = Protocols; sourceTree = ""; @@ -182,7 +183,6 @@ EA3361B9288B2BE30071C351 /* Utilities */ = { isa = PBXGroup; children = ( - EA3361BA288B2C010071C351 /* VDSHelper.swift */, EA3361BC288B2C760071C351 /* TypeAlias.swift */, ); path = Utilities; @@ -297,8 +297,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EA3361C328902D960071C351 /* VDSToggle.swift in Sources */, + EA3361C5289030FC0071C351 /* Accessable.swift in Sources */, EA3361A2288B1E840071C351 /* ToggleModelProtocol.swift in Sources */, - EA3361BB288B2C010071C351 /* VDSHelper.swift in Sources */, EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */, EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */, EA3361B3288B265D0071C351 /* Changable.swift in Sources */, @@ -307,7 +308,6 @@ EA3361B6288B2A410071C351 /* Control.swift in Sources */, EA3361B1288B26490071C351 /* Invertable.swift in Sources */, EA3361AD288B26190071C351 /* DataTrackable.swift in Sources */, - EA33619F288B1E4D0071C351 /* VDSToggle.swift in Sources */, EA3361B8288B2AAA0071C351 /* ViewProtocol.swift in Sources */, EA3361BF288B2EA60071C351 /* Modelable.swift in Sources */, EA3361A8288B23300071C351 /* UIColor.swift in Sources */, diff --git a/VDS/BaseClasses/Control.swift b/VDS/BaseClasses/Control.swift index 3cb6cbc2..9d947b7a 100644 --- a/VDS/BaseClasses/Control.swift +++ b/VDS/BaseClasses/Control.swift @@ -8,11 +8,12 @@ import Foundation import UIKit -@objcMembers open class Control: UIControl { +@objcMembers open class Control: UIControl, Modelable, ViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- private var initialSetupPerformed = false + public var model: ModelType? //-------------------------------------------------- // MARK: - Initializers @@ -43,20 +44,21 @@ import UIKit setupView() } } + + open func set(with model: ModelType) { + self.model = model + } open func reset() { backgroundColor = .clear } -} - -// MARK: - ViewProtocol -extension Control: ViewProtocol { + // MARK: - ViewProtocol open func updateView(_ size: CGFloat) { } /// Will be called only once. open func setupView() { translatesAutoresizingMaskIntoConstraints = false insetsLayoutMarginsFromSafeArea = false - } + } } diff --git a/VDS/Components/Toggle/ToggleModelProtocol.swift b/VDS/Components/Toggle/ToggleModelProtocol.swift index ec5d858a..11f3a25e 100644 --- a/VDS/Components/Toggle/ToggleModelProtocol.swift +++ b/VDS/Components/Toggle/ToggleModelProtocol.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol ToggleModelProtocol: Invertable, FormFieldable, DataTrackable, Disabling { +public protocol ToggleModelProtocol: Invertable, FormFieldable, DataTrackable, Disabling, Accessable { var id: String? { get set } var hideText: Bool { get set } var on: Bool { get set } diff --git a/VDS/Components/Toggle/VDSToggle.swift b/VDS/Components/Toggle/VDSToggle.swift index 9d448c8f..67fa9231 100644 --- a/VDS/Components/Toggle/VDSToggle.swift +++ b/VDS/Components/Toggle/VDSToggle.swift @@ -16,13 +16,11 @@ import VDSColorTokens Container: The background of the toggle control. Knob: The circular indicator that slides on the container. */ -@objcMembers open class VDSToggle: Control, Modelable, Changable { - public typealias ModelType = ToggleModelProtocol +@objcMembers open class VDSToggle: Control, Changable { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public var model: ModelType? - /// Holds the on and off colors for the container. public var containerTintColor: (on: UIColor, off: UIColor) = (on: .green, off: .black) @@ -38,14 +36,16 @@ import VDSColorTokens public var onChange: Blocks.ActionBlock? // Sizes are from InVision design specs. - static let containerSize = CGSize(width: 51, height: 31) - static let knobSize = CGSize(width: 28, height: 28) + public static var containerSize = CGSize(width: 51, height: 31) + open class func getContainerScaledSize() -> CGSize { return Self.containerSize } + public static var knobSize = CGSize(width: 28, height: 28) + open class func getKnobScaledSize() -> CGSize { return Self.knobSize } + private var knobView: UIView = { let view = UIView() view.translatesAutoresizingMaskIntoConstraints = false view.backgroundColor = .white - view.layer.cornerRadius = VDSToggle.getKnobHeight() / 2.0 return view }() @@ -58,7 +58,7 @@ import VDSColorTokens isUserInteractionEnabled = isEnabled changeStateNoAnimation(isEnabled ? isOn : false) setToggleAppearanceFromState() - accessibilityHint = VDSHelper.localizedString?(isEnabled ? "AccToggleHint" : "AccDisabled") + setAccessibilityHint(isEnabled) } } @@ -84,7 +84,7 @@ import VDSColorTokens UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [], animations: { self.constrainKnob() - self.knobWidthConstraint?.constant = Self.getKnobWidth() + self.knobWidthConstraint?.constant = Self.getKnobScaledSize().width self.layoutIfNeeded() }, completion: nil) @@ -94,7 +94,7 @@ import VDSColorTokens } model?.on = isOn - accessibilityValue = VDSHelper.localizedString?(isOn ? "AccOn" : "AccOff") + setAccessibilityValue(isOn) setNeedsLayout() layoutIfNeeded() } @@ -137,11 +137,6 @@ import VDSColorTokens //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- - public required init(model: ToggleModelProtocol) { - self.model = model - super.init() - } - public required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -161,40 +156,48 @@ import VDSColorTokens public override func updateView(_ size: CGFloat) { super.updateView(size) - heightConstraint?.constant = Self.getContainerHeight() - widthConstraint?.constant = Self.getContainerWidth() + let containerSize = Self.getContainerScaledSize() + let knobSize = Self.getKnobScaledSize() + + heightConstraint?.constant = containerSize.height + widthConstraint?.constant = containerSize.width - knobHeightConstraint?.constant = Self.getKnobHeight() - knobWidthConstraint?.constant = Self.getKnobWidth() + knobHeightConstraint?.constant = knobSize.height + knobWidthConstraint?.constant = knobSize.width - layer.cornerRadius = Self.getContainerHeight() / 2.0 - knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0 + layer.cornerRadius = containerSize.height / 2.0 + knobView.layer.cornerRadius = knobSize.height / 2.0 changeStateNoAnimation(isOn) } public override func setupView() { super.setupView() - + + let containerSize = Self.getContainerScaledSize() + let knobSize = Self.getKnobScaledSize() + isAccessibilityElement = true - accessibilityHint = VDSHelper.localizedString?( "AccToggleHint") - accessibilityLabel = VDSHelper.localizedString?( "Toggle_buttonlabel") + setAccessibilityHint() + setAccessibilityLabel() accessibilityTraits = .button - heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height) + heightConstraint = heightAnchor.constraint(equalToConstant: containerSize.height) heightConstraint?.isActive = true - widthConstraint = widthAnchor.constraint(equalToConstant: Self.containerSize.width) + widthConstraint = widthAnchor.constraint(equalToConstant: containerSize.width) widthConstraint?.isActive = true - layer.cornerRadius = Self.getContainerHeight() / 2.0 + layer.cornerRadius = containerSize.height / 2.0 + knobView.layer.cornerRadius = knobSize.height / 2.0 + backgroundColor = containerTintColor.off addSubview(knobView) - knobHeightConstraint = knobView.heightAnchor.constraint(equalToConstant: Self.knobSize.height) + knobHeightConstraint = knobView.heightAnchor.constraint(equalToConstant: knobSize.height) knobHeightConstraint?.isActive = true - knobWidthConstraint = knobView.widthAnchor.constraint(equalToConstant: Self.knobSize.width) + knobWidthConstraint = knobView.widthAnchor.constraint(equalToConstant: knobSize.width) knobWidthConstraint?.isActive = true knobView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true @@ -208,35 +211,11 @@ import VDSColorTokens backgroundColor = containerTintColor.off knobView.backgroundColor = knobTintColor.off - accessibilityLabel = VDSHelper.localizedString?( "Toggle_buttonlabel") + setAccessibilityLabel() isAnimated = true onChange = nil } - - public static func getContainerWidth() -> CGFloat { - let size = Self.containerSize.width - guard let block = VDSHelper.sizeForDevice else { return size } - return block(size, .iPadPortrait, CGFloat(size * 1.5)) - } - - public static func getContainerHeight() -> CGFloat { - let size = Self.containerSize.height - guard let block = VDSHelper.sizeForDevice else { return size } - return block(size, .iPadPortrait, CGFloat(size * 1.5)) - } - - public static func getKnobWidth() -> CGFloat { - let size = Self.knobSize.width - guard let block = VDSHelper.sizeForDevice else { return size } - return block(size, .iPadPortrait, CGFloat(size * 1.5)) - } - - public static func getKnobHeight() -> CGFloat { - let size = Self.knobSize.width - guard let block = VDSHelper.sizeForDevice else { return size } - return block(size, .iPadPortrait, CGFloat(size * 1.5)) - } - + //-------------------------------------------------- // MARK: - Actions //-------------------------------------------------- @@ -321,27 +300,27 @@ import VDSColorTokens } public func knobReformAnimation() { + let knobWidth = Self.getKnobScaledSize().width if isAnimated { UIView.animate(withDuration: 0.1, animations: { - self.knobWidthConstraint?.constant = Self.getKnobWidth() + self.knobWidthConstraint?.constant = knobWidth self.layoutIfNeeded() }, completion: nil) } else { - knobWidthConstraint?.constant = Self.getKnobWidth() + knobWidthConstraint?.constant = knobWidth layoutIfNeeded() } } // MARK:- MoleculeViewProtocol - open func set(with model: ModelType) { + open override func set(with model: ModelType) { self.model = model isOn = model.on changeStateNoAnimation(isOn) isAnimated = true isEnabled = !model.disabled } - } diff --git a/VDS/Protocols/Accessable.swift b/VDS/Protocols/Accessable.swift new file mode 100644 index 00000000..7fa273fc --- /dev/null +++ b/VDS/Protocols/Accessable.swift @@ -0,0 +1,52 @@ +// +// Accessable.swift +// VDS +// +// Created by Matt Bruce on 7/26/22. +// + +import Foundation +import UIKit + +public protocol Accessable { + var accessibilityHintEnabled: String? { get set } + var accessibilityHintDisabled: String? { get set } + var accessibilityValueEnabled: String? { get set } + var accessibilityValueDisabled: String? { get set } + var accessibilityLabelEnabled: String? { get set } + var accessibilityLabelDisabled: String? { get set } +} + +//Helpers to set within the UIControl +extension Modelable where Self: UIControl { + private var accessableModel: Accessable? { + guard let model = self.model as? Accessable else { + return nil + } + return model + } + + public func setAccessibilityHint(_ enabled: Bool = true) { + if let value = accessableModel?.accessibilityHintEnabled, enabled { + accessibilityHint = value + } else if let value = accessableModel?.accessibilityHintDisabled, !enabled { + accessibilityHint = value + } + } + + public func setAccessibilityValue(_ enabled: Bool = true) { + if let value = accessableModel?.accessibilityValueEnabled, enabled { + accessibilityValue = value + } else if let value = accessableModel?.accessibilityValueDisabled, !enabled { + accessibilityValue = value + } + } + + public func setAccessibilityLabel(_ enabled: Bool = true) { + if let value = accessableModel?.accessibilityLabelEnabled, enabled { + accessibilityLabel = value + } else if let value = accessableModel?.accessibilityLabelDisabled, !enabled { + accessibilityLabel = value + } + } +} diff --git a/VDS/Utilities/VDSHelper.swift b/VDS/Utilities/VDSHelper.swift deleted file mode 100644 index 30d5cd3c..00000000 --- a/VDS/Utilities/VDSHelper.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// VDSHelper.swift -// VDS -// -// Created by Matt Bruce on 7/22/22. -// - -import Foundation - -public struct VDSHelper { - public static var localizedString: Blocks.StringValueBlock? - - public static var sizeForDevice: Blocks.SizeForDeviceTypeBlock? -}