first cut of Toggle
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
97d231089c
commit
6b77c2829a
@ -11,6 +11,21 @@
|
|||||||
EA336177288B19210071C351 /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA33616C288B19200071C351 /* VDS.framework */; };
|
EA336177288B19210071C351 /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA33616C288B19200071C351 /* VDS.framework */; };
|
||||||
EA33617C288B19210071C351 /* VDSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33617B288B19210071C351 /* VDSTests.swift */; };
|
EA33617C288B19210071C351 /* VDSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA33617B288B19210071C351 /* VDSTests.swift */; };
|
||||||
EA33617D288B19210071C351 /* VDS.h in Headers */ = {isa = PBXBuildFile; fileRef = EA33616F288B19200071C351 /* VDS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
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 */; };
|
||||||
|
EA3361AD288B26190071C351 /* DataTrackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361AC288B26190071C351 /* DataTrackable.swift */; };
|
||||||
|
EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361AE288B26310071C351 /* FormFieldable.swift */; };
|
||||||
|
EA3361B1288B26490071C351 /* Invertable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361B0288B26490071C351 /* Invertable.swift */; };
|
||||||
|
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 */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -29,6 +44,21 @@
|
|||||||
EA336170288B19200071C351 /* VDS.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = VDS.docc; sourceTree = "<group>"; };
|
EA336170288B19200071C351 /* VDS.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = VDS.docc; sourceTree = "<group>"; };
|
||||||
EA336176288B19210071C351 /* VDSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VDSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
EA336176288B19210071C351 /* VDSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VDSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
EA33617B288B19210071C351 /* VDSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSTests.swift; sourceTree = "<group>"; };
|
EA33617B288B19210071C351 /* VDSTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSTests.swift; sourceTree = "<group>"; };
|
||||||
|
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 = "<absolute>"; };
|
||||||
|
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 = "<absolute>"; };
|
||||||
|
EA33619E288B1E4D0071C351 /* VDSToggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSToggle.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361A1288B1E840071C351 /* ToggleModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361A7288B23300071C351 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361A9288B25E40071C351 /* Disabling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Disabling.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361AC288B26190071C351 /* DataTrackable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTrackable.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361AE288B26310071C351 /* FormFieldable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldable.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361B0288B26490071C351 /* Invertable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Invertable.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361B2288B265D0071C351 /* Changable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Changable.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361B5288B2A410071C351 /* Control.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Control.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361BA288B2C010071C351 /* VDSHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSHelper.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361BC288B2C760071C351 /* TypeAlias.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = "<group>"; };
|
||||||
|
EA3361BE288B2EA60071C351 /* Modelable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modelable.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -36,6 +66,8 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
EA336195288B1C420071C351 /* VDSColorTokens.xcframework in Frameworks */,
|
||||||
|
EA336197288B1C420071C351 /* VDSFormControlsTokens.xcframework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -56,6 +88,7 @@
|
|||||||
EA33616E288B19200071C351 /* VDS */,
|
EA33616E288B19200071C351 /* VDS */,
|
||||||
EA33617A288B19210071C351 /* VDSTests */,
|
EA33617A288B19210071C351 /* VDSTests */,
|
||||||
EA33616D288B19200071C351 /* Products */,
|
EA33616D288B19200071C351 /* Products */,
|
||||||
|
EA33618D288B1C0C0071C351 /* Frameworks */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -71,8 +104,13 @@
|
|||||||
EA33616E288B19200071C351 /* VDS */ = {
|
EA33616E288B19200071C351 /* VDS */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
EA33616F288B19200071C351 /* VDS.h */,
|
|
||||||
EA336170288B19200071C351 /* VDS.docc */,
|
EA336170288B19200071C351 /* VDS.docc */,
|
||||||
|
EA33616F288B19200071C351 /* VDS.h */,
|
||||||
|
EA3361B4288B2A360071C351 /* BaseClasses */,
|
||||||
|
EA33619D288B1E330071C351 /* Components */,
|
||||||
|
EA3361A6288B23240071C351 /* Extensions */,
|
||||||
|
EA3361AB288B25EC0071C351 /* Protocols */,
|
||||||
|
EA3361B9288B2BE30071C351 /* Utilities */,
|
||||||
);
|
);
|
||||||
path = VDS;
|
path = VDS;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -85,6 +123,71 @@
|
|||||||
path = VDSTests;
|
path = VDSTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
EA33618D288B1C0C0071C351 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA33618E288B1C0C0071C351 /* VDSColorTokens.xcframework */,
|
||||||
|
EA33618F288B1C0C0071C351 /* VDSFormControlsTokens.xcframework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA33619D288B1E330071C351 /* Components */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA3361A0288B1E6F0071C351 /* Toggle */,
|
||||||
|
);
|
||||||
|
path = Components;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA3361A0288B1E6F0071C351 /* Toggle */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA33619E288B1E4D0071C351 /* VDSToggle.swift */,
|
||||||
|
EA3361A1288B1E840071C351 /* ToggleModelProtocol.swift */,
|
||||||
|
);
|
||||||
|
path = Toggle;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA3361A6288B23240071C351 /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA3361A7288B23300071C351 /* UIColor.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA3361AB288B25EC0071C351 /* Protocols */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA3361B2288B265D0071C351 /* Changable.swift */,
|
||||||
|
EA3361AC288B26190071C351 /* DataTrackable.swift */,
|
||||||
|
EA3361A9288B25E40071C351 /* Disabling.swift */,
|
||||||
|
EA3361AE288B26310071C351 /* FormFieldable.swift */,
|
||||||
|
EA3361B0288B26490071C351 /* Invertable.swift */,
|
||||||
|
EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */,
|
||||||
|
EA3361BE288B2EA60071C351 /* Modelable.swift */,
|
||||||
|
);
|
||||||
|
path = Protocols;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA3361B4288B2A360071C351 /* BaseClasses */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA3361B5288B2A410071C351 /* Control.swift */,
|
||||||
|
);
|
||||||
|
path = BaseClasses;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
EA3361B9288B2BE30071C351 /* Utilities */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EA3361BA288B2C010071C351 /* VDSHelper.swift */,
|
||||||
|
EA3361BC288B2C760071C351 /* TypeAlias.swift */,
|
||||||
|
);
|
||||||
|
path = Utilities;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
@ -194,7 +297,20 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
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 */,
|
||||||
EA336171288B19200071C351 /* VDS.docc in Sources */,
|
EA336171288B19200071C351 /* VDS.docc in Sources */,
|
||||||
|
EA3361AA288B25E40071C351 /* Disabling.swift in Sources */,
|
||||||
|
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 */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -340,13 +456,15 @@
|
|||||||
EA336181288B19210071C351 /* Debug */ = {
|
EA336181288B19210071C351 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
BITCODE_GENERATION_MODE = bitcode;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = FCMA4QKS77;
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
ENABLE_BITCODE = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
@ -370,13 +488,15 @@
|
|||||||
EA336182288B19210071C351 /* Release */ = {
|
EA336182288B19210071C351 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
BITCODE_GENERATION_MODE = bitcode;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = FCMA4QKS77;
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
DYLIB_CURRENT_VERSION = 1;
|
DYLIB_CURRENT_VERSION = 1;
|
||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
ENABLE_BITCODE = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
@ -400,6 +520,7 @@
|
|||||||
EA336184288B19210071C351 /* Debug */ = {
|
EA336184288B19210071C351 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = FCMA4QKS77;
|
DEVELOPMENT_TEAM = FCMA4QKS77;
|
||||||
@ -416,6 +537,7 @@
|
|||||||
EA336185288B19210071C351 /* Release */ = {
|
EA336185288B19210071C351 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = FCMA4QKS77;
|
DEVELOPMENT_TEAM = FCMA4QKS77;
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<key>VDS.xcscheme_^#shared#^_</key>
|
<key>VDS.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>5</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
|
|||||||
62
VDS/BaseClasses/Control.swift
Normal file
62
VDS/BaseClasses/Control.swift
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// Control.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class Control: UIControl {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public override init(frame: CGRect) {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
super.init(frame: .zero)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
fatalError("Control does not support xib.")
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Setup
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func initialSetup() {
|
||||||
|
if !initialSetupPerformed {
|
||||||
|
initialSetupPerformed = true
|
||||||
|
setupView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func reset() {
|
||||||
|
backgroundColor = .clear
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - ViewProtocol
|
||||||
|
extension Control: ViewProtocol {
|
||||||
|
|
||||||
|
open func updateView(_ size: CGFloat) { }
|
||||||
|
|
||||||
|
/// Will be called only once.
|
||||||
|
open func setupView() {
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
insetsLayoutMarginsFromSafeArea = false
|
||||||
|
}
|
||||||
|
}
|
||||||
15
VDS/Components/Toggle/ToggleModelProtocol.swift
Normal file
15
VDS/Components/Toggle/ToggleModelProtocol.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// ToggleModel.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public protocol ToggleModelProtocol: Invertable, FormFieldable, DataTrackable, Disabling {
|
||||||
|
var id: String? { get set }
|
||||||
|
var hideText: Bool { get set }
|
||||||
|
var on: Bool { get set }
|
||||||
|
}
|
||||||
347
VDS/Components/Toggle/VDSToggle.swift
Normal file
347
VDS/Components/Toggle/VDSToggle.swift
Normal file
@ -0,0 +1,347 @@
|
|||||||
|
//
|
||||||
|
// Toggle.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import VDSColorTokens
|
||||||
|
/**
|
||||||
|
A custom implementation of Apple's UISwitch.
|
||||||
|
|
||||||
|
By default this class begins in the off state.
|
||||||
|
|
||||||
|
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
|
||||||
|
//--------------------------------------------------
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
/// Holds the on and off colors for the knob.
|
||||||
|
public var knobTintColor: (on: UIColor, off: UIColor) = (on: .white, off: .white)
|
||||||
|
|
||||||
|
/// Holds the on and off colors for the disabled state..
|
||||||
|
public var disabledTintColor: (container: UIColor, knob: UIColor) = (container: .gray, knob: .white)
|
||||||
|
|
||||||
|
/// Set this flag to false if you do not want to animate state changes.
|
||||||
|
public var isAnimated = true
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
private var knobView: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.backgroundColor = .white
|
||||||
|
view.layer.cornerRadius = VDSToggle.getKnobHeight() / 2.0
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Computed Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override var isEnabled: Bool {
|
||||||
|
didSet {
|
||||||
|
isUserInteractionEnabled = isEnabled
|
||||||
|
changeStateNoAnimation(isEnabled ? isOn : false)
|
||||||
|
setToggleAppearanceFromState()
|
||||||
|
accessibilityHint = VDSHelper.localizedString?(isEnabled ? "AccToggleHint" : "AccDisabled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simple means to prevent user interaction with the toggle.
|
||||||
|
public var isLocked: Bool = false {
|
||||||
|
didSet { isUserInteractionEnabled = !isLocked }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The state on the toggle. Default value: false.
|
||||||
|
open var isOn: Bool = false {
|
||||||
|
didSet {
|
||||||
|
if isAnimated {
|
||||||
|
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
|
||||||
|
if self.isOn {
|
||||||
|
self.knobView.backgroundColor = self.knobTintColor.on
|
||||||
|
self.backgroundColor = self.containerTintColor.on
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.knobView.backgroundColor = self.knobTintColor.off
|
||||||
|
self.backgroundColor = self.containerTintColor.off
|
||||||
|
}
|
||||||
|
}, completion: nil)
|
||||||
|
|
||||||
|
UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [], animations: {
|
||||||
|
self.constrainKnob()
|
||||||
|
self.knobWidthConstraint?.constant = Self.getKnobWidth()
|
||||||
|
self.layoutIfNeeded()
|
||||||
|
}, completion: nil)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setToggleAppearanceFromState()
|
||||||
|
self.constrainKnob()
|
||||||
|
}
|
||||||
|
|
||||||
|
model?.on = isOn
|
||||||
|
accessibilityValue = VDSHelper.localizedString?(isOn ? "AccOn" : "AccOff")
|
||||||
|
setNeedsLayout()
|
||||||
|
layoutIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Constraints
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private var knobLeadingConstraint: NSLayoutConstraint?
|
||||||
|
private var knobTrailingConstraint: NSLayoutConstraint?
|
||||||
|
private var knobHeightConstraint: NSLayoutConstraint?
|
||||||
|
private var knobWidthConstraint: NSLayoutConstraint?
|
||||||
|
private var heightConstraint: NSLayoutConstraint?
|
||||||
|
private var widthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
private func constrainKnob() {
|
||||||
|
|
||||||
|
knobLeadingConstraint?.isActive = false
|
||||||
|
knobTrailingConstraint?.isActive = false
|
||||||
|
|
||||||
|
_ = isOn ? constrainKnobOn() : constrainKnobOff()
|
||||||
|
|
||||||
|
knobTrailingConstraint?.isActive = true
|
||||||
|
knobLeadingConstraint?.isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func constrainKnobOn() {
|
||||||
|
|
||||||
|
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 2)
|
||||||
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func constrainKnobOff() {
|
||||||
|
|
||||||
|
knobTrailingConstraint = trailingAnchor.constraint(greaterThanOrEqualTo: knobView.trailingAnchor)
|
||||||
|
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
public required init(model: ToggleModelProtocol) {
|
||||||
|
self.model = model
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
}
|
||||||
|
|
||||||
|
public convenience override init() {
|
||||||
|
self.init(frame: .zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public override func updateView(_ size: CGFloat) {
|
||||||
|
super.updateView(size)
|
||||||
|
|
||||||
|
heightConstraint?.constant = Self.getContainerHeight()
|
||||||
|
widthConstraint?.constant = Self.getContainerWidth()
|
||||||
|
|
||||||
|
knobHeightConstraint?.constant = Self.getKnobHeight()
|
||||||
|
knobWidthConstraint?.constant = Self.getKnobWidth()
|
||||||
|
|
||||||
|
layer.cornerRadius = Self.getContainerHeight() / 2.0
|
||||||
|
knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0
|
||||||
|
|
||||||
|
changeStateNoAnimation(isOn)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
|
||||||
|
isAccessibilityElement = true
|
||||||
|
accessibilityHint = VDSHelper.localizedString?( "AccToggleHint")
|
||||||
|
accessibilityLabel = VDSHelper.localizedString?( "Toggle_buttonlabel")
|
||||||
|
accessibilityTraits = .button
|
||||||
|
|
||||||
|
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
|
||||||
|
heightConstraint?.isActive = true
|
||||||
|
|
||||||
|
widthConstraint = widthAnchor.constraint(equalToConstant: Self.containerSize.width)
|
||||||
|
widthConstraint?.isActive = true
|
||||||
|
|
||||||
|
layer.cornerRadius = Self.getContainerHeight() / 2.0
|
||||||
|
backgroundColor = containerTintColor.off
|
||||||
|
|
||||||
|
addSubview(knobView)
|
||||||
|
|
||||||
|
knobHeightConstraint = knobView.heightAnchor.constraint(equalToConstant: Self.knobSize.height)
|
||||||
|
knobHeightConstraint?.isActive = true
|
||||||
|
knobWidthConstraint = knobView.widthAnchor.constraint(equalToConstant: Self.knobSize.width)
|
||||||
|
knobWidthConstraint?.isActive = true
|
||||||
|
knobView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
|
||||||
|
knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
|
||||||
|
bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true
|
||||||
|
|
||||||
|
constrainKnobOff()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func reset() {
|
||||||
|
super.reset()
|
||||||
|
|
||||||
|
backgroundColor = containerTintColor.off
|
||||||
|
knobView.backgroundColor = knobTintColor.off
|
||||||
|
accessibilityLabel = VDSHelper.localizedString?( "Toggle_buttonlabel")
|
||||||
|
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
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
|
||||||
|
super.sendAction(action, to: target, for: event)
|
||||||
|
toggleAndAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
open override func sendActions(for controlEvents: UIControl.Event) {
|
||||||
|
super.sendActions(for: controlEvents)
|
||||||
|
toggleAndAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This will toggle the state of the Toggle and execute the actionBlock if provided.
|
||||||
|
public func toggleAndAction() {
|
||||||
|
isOn.toggle()
|
||||||
|
onChange?()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func changeStateNoAnimation(_ state: Bool) {
|
||||||
|
|
||||||
|
// Hold state in case User wanted isAnimated to remain off.
|
||||||
|
let isAnimatedState = isAnimated
|
||||||
|
|
||||||
|
isAnimated = false
|
||||||
|
isOn = state
|
||||||
|
isAnimated = isAnimatedState
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func accessibilityActivate() -> Bool {
|
||||||
|
// Hold state in case User wanted isAnimated to remain off.
|
||||||
|
guard isUserInteractionEnabled else { return false }
|
||||||
|
let isAnimatedState = isAnimated
|
||||||
|
isAnimated = false
|
||||||
|
sendActions(for: .touchUpInside)
|
||||||
|
isAnimated = isAnimatedState
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - UIResponder
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
|
|
||||||
|
UIView.animate(withDuration: 0.1, animations: {
|
||||||
|
self.knobWidthConstraint?.constant += Constants.PaddingOne
|
||||||
|
self.layoutIfNeeded()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
sendActions(for: .touchUpInside)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
|
||||||
|
|
||||||
|
knobReformAnimation()
|
||||||
|
sendActions(for: .touchCancel)
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Animations
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public func setToggleAppearanceFromState() {
|
||||||
|
|
||||||
|
backgroundColor = isEnabled ? isOn ? containerTintColor.on : containerTintColor.off : disabledTintColor.container
|
||||||
|
knobView.backgroundColor = isEnabled ? isOn ? knobTintColor.on : knobTintColor.off : disabledTintColor.knob
|
||||||
|
}
|
||||||
|
|
||||||
|
public func knobReformAnimation() {
|
||||||
|
|
||||||
|
if isAnimated {
|
||||||
|
UIView.animate(withDuration: 0.1, animations: {
|
||||||
|
self.knobWidthConstraint?.constant = Self.getKnobWidth()
|
||||||
|
self.layoutIfNeeded()
|
||||||
|
}, completion: nil)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
knobWidthConstraint?.constant = Self.getKnobWidth()
|
||||||
|
layoutIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK:- MoleculeViewProtocol
|
||||||
|
open func set(with model: ModelType) {
|
||||||
|
self.model = model
|
||||||
|
isOn = model.on
|
||||||
|
changeStateNoAnimation(isOn)
|
||||||
|
isAnimated = true
|
||||||
|
isEnabled = !model.disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
113
VDS/Extensions/UIColor.swift
Normal file
113
VDS/Extensions/UIColor.swift
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// UIColor.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIColor {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Functions
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
/// Convenience to get a grayscale UIColor where the same value is used for red, green, and blue.
|
||||||
|
public class func grayscale(rgb: Int, alpha: CGFloat = 1.0) -> UIColor {
|
||||||
|
|
||||||
|
let grayscale = CGFloat(rgb) / 255.0
|
||||||
|
return UIColor(red: grayscale, green: grayscale, blue: grayscale, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience to get a UIColor.
|
||||||
|
public class func color8Bits(red: Int, green: Int, blue: Int, alpha: CGFloat = 1.0) -> UIColor {
|
||||||
|
|
||||||
|
return UIColor(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience to get a UIColor.
|
||||||
|
public class func color8Bits(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat = 1.0) -> UIColor {
|
||||||
|
|
||||||
|
return UIColor(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets UIColor via an 8 digit hex string.
|
||||||
|
public class func getColorBy(hex: String) -> UIColor {
|
||||||
|
|
||||||
|
var hexint: UInt64 = 0
|
||||||
|
|
||||||
|
let scanner = Scanner(string: hex)
|
||||||
|
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
|
||||||
|
scanner.scanHexInt64(&hexint)
|
||||||
|
|
||||||
|
return UIColor(red: (CGFloat((hexint & 0xFF0000) >> 16)) / 255,
|
||||||
|
green: (CGFloat((hexint & 0xFF00) >> 8)) / 255,
|
||||||
|
blue: (CGFloat(hexint & 0xFF)) / 255,
|
||||||
|
alpha: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets UIColor via an 8 digit hex string. The last two being the alpha channel.
|
||||||
|
public class func getColorWithTransparencyBy(hex: String) -> UIColor {
|
||||||
|
|
||||||
|
var hexint: UInt64 = 0
|
||||||
|
|
||||||
|
let scanner = Scanner(string: hex)
|
||||||
|
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#")
|
||||||
|
scanner.scanHexInt64(&hexint)
|
||||||
|
|
||||||
|
return UIColor(red: (CGFloat((hexint & 0xFF000000) >> 24)) / 255,
|
||||||
|
green: (CGFloat((hexint & 0xFF0000) >> 16)) / 255,
|
||||||
|
blue: (CGFloat((hexint & 0xFF00) >> 8)) / 255,
|
||||||
|
alpha: (CGFloat(hexint & 0xFF)) / 255)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class func gradientColor(_ color: UIColor?) -> UIColor {
|
||||||
|
|
||||||
|
var h: CGFloat = 0
|
||||||
|
var s: CGFloat = 0
|
||||||
|
var b: CGFloat = 0
|
||||||
|
var a: CGFloat = 0
|
||||||
|
|
||||||
|
if color?.getHue(&h, saturation: &s, brightness: &b, alpha: &a) ?? false {
|
||||||
|
return UIColor(hue: h, saturation: max(s - 0.17, 0.0), brightness: min(b - 0.03, 1.0), alpha: a)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .white
|
||||||
|
}
|
||||||
|
|
||||||
|
/// - parameter color: The UIColor intended to retrieve its hex value.
|
||||||
|
public class func hexString(for color: UIColor) -> String? {
|
||||||
|
|
||||||
|
guard let components = color.cgColor.components else { return nil }
|
||||||
|
|
||||||
|
let numberOfComponents = color.cgColor.numberOfComponents
|
||||||
|
if numberOfComponents >= 3 {
|
||||||
|
// RGB color space
|
||||||
|
let r = Int(CGFloat(components[0]) * 255)
|
||||||
|
let g = Int(CGFloat(components[1]) * 255)
|
||||||
|
let b = Int(CGFloat(components[2]) * 255)
|
||||||
|
|
||||||
|
// If alpha of color is less than 1.0 then alpha hex is relevant.
|
||||||
|
if color.cgColor.numberOfComponents == 4 && components[3] < 1.0 {
|
||||||
|
let a = Int(CGFloat(components[3]) * 255)
|
||||||
|
return String(format: "%02X%02X%02X%02X", r, g, b, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(format: "%02X%02X%02X", r, g, b)
|
||||||
|
} else if numberOfComponents == 2 {
|
||||||
|
// Monochromatic color space
|
||||||
|
let value = Int(CGFloat(components[0]) * 255)
|
||||||
|
|
||||||
|
// If alpha of color is less than 1.0 then alpha hex is relevant.
|
||||||
|
if components[1] < 1.0 {
|
||||||
|
let alpha = Int(CGFloat(components[1]) * 255)
|
||||||
|
return String(format: "%02X%02X%02X%02X", value, value, value, alpha)
|
||||||
|
}
|
||||||
|
return String(format: "%02X%02X%02X", value, value, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
12
VDS/Protocols/Changable.swift
Normal file
12
VDS/Protocols/Changable.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// Changable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Changable {
|
||||||
|
var onChange: Blocks.ActionBlock? { get set }
|
||||||
|
}
|
||||||
14
VDS/Protocols/DataTrackable.swift
Normal file
14
VDS/Protocols/DataTrackable.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// DataTrackable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol DataTrackable {
|
||||||
|
var dataAnalyticsTrack: String? { get set }
|
||||||
|
var dataClickStream: String? { get set }
|
||||||
|
var dataTrack: String? { get set }
|
||||||
|
}
|
||||||
12
VDS/Protocols/Disabling.swift
Normal file
12
VDS/Protocols/Disabling.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// Disabling.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Disabling {
|
||||||
|
var disabled: Bool { get set }
|
||||||
|
}
|
||||||
13
VDS/Protocols/FormFieldable.swift
Normal file
13
VDS/Protocols/FormFieldable.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// FormFieldable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol FormFieldable {
|
||||||
|
var inputId: String? { get set }
|
||||||
|
var value: AnyHashable? { get set }
|
||||||
|
}
|
||||||
12
VDS/Protocols/Invertable.swift
Normal file
12
VDS/Protocols/Invertable.swift
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// Invertable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Invertable {
|
||||||
|
var inverted: Bool { get set }
|
||||||
|
}
|
||||||
14
VDS/Protocols/Modelable.swift
Normal file
14
VDS/Protocols/Modelable.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Modelable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Modelable {
|
||||||
|
associatedtype ModelType
|
||||||
|
var model: ModelType? { get set }
|
||||||
|
func set(with model: ModelType)
|
||||||
|
}
|
||||||
19
VDS/Protocols/ViewProtocol.swift
Normal file
19
VDS/Protocols/ViewProtocol.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ViewProtocol.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public protocol ViewProtocol {
|
||||||
|
|
||||||
|
// Updates the ui to fit the right size.
|
||||||
|
func updateView(_ size: CGFloat)
|
||||||
|
|
||||||
|
// Can setup ui here. Should be called in the initialization functions.
|
||||||
|
func setupView()
|
||||||
|
}
|
||||||
|
|
||||||
31
VDS/Utilities/TypeAlias.swift
Normal file
31
VDS/Utilities/TypeAlias.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// TypeAlias.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/22/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
public struct Blocks {
|
||||||
|
public typealias ActionBlock = () -> ()
|
||||||
|
public typealias StringValueBlock = (_ key: String) -> (String)
|
||||||
|
public typealias SizeForDeviceTypeBlock = (_ size: CGFloat, _ deviceType: Enums.SizeDeviceType, _ deviceSize: CGFloat) -> (CGFloat)
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Constants {
|
||||||
|
public static let PaddingOne = 10.0
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Enums {
|
||||||
|
public enum SizeDeviceType {
|
||||||
|
case iPhone4Height
|
||||||
|
case iPhone5Height
|
||||||
|
case iPhone
|
||||||
|
case largeiPhone
|
||||||
|
case iPadPortrait
|
||||||
|
case iPadLandscape
|
||||||
|
case iPadProLandscape
|
||||||
|
}
|
||||||
|
}
|
||||||
14
VDS/Utilities/VDSHelper.swift
Normal file
14
VDS/Utilities/VDSHelper.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// 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?
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user