Merge branch 'develop' into feature/subject
This commit is contained in:
commit
c0090deac9
@ -13,6 +13,13 @@
|
|||||||
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
|
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
|
||||||
5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; };
|
5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; };
|
||||||
EA0D1C372A681CCE00E5C127 /* ToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C362A681CCE00E5C127 /* ToggleView.swift */; };
|
EA0D1C372A681CCE00E5C127 /* ToggleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C362A681CCE00E5C127 /* ToggleView.swift */; };
|
||||||
|
EA0D1C392A6AD4DF00E5C127 /* Typography+SpacingConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */; };
|
||||||
|
EA0D1C3B2A6AD51B00E5C127 /* Typogprahy+Styles.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */; };
|
||||||
|
EA0D1C3D2A6AD57600E5C127 /* Typography+Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */; };
|
||||||
|
EA0D1C3F2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */; };
|
||||||
|
EA0D1C412A6AD61C00E5C127 /* Typography+Additional.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */; };
|
||||||
|
EA0D1C432A6AD70900E5C127 /* VDSTypography.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */; };
|
||||||
|
EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */; };
|
||||||
EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */; };
|
EA0FC2C62914222900DF80B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */; };
|
||||||
EA1DA1CB2A2E36DC001C51D2 /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */; };
|
EA1DA1CB2A2E36DC001C51D2 /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */; };
|
||||||
EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1F266128B945070033E859 /* RadioSwatch.swift */; };
|
EA1F266528B945070033E859 /* RadioSwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1F266128B945070033E859 /* RadioSwatch.swift */; };
|
||||||
@ -150,6 +157,13 @@
|
|||||||
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
|
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
|
||||||
5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
||||||
EA0D1C362A681CCE00E5C127 /* ToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleView.swift; sourceTree = "<group>"; };
|
EA0D1C362A681CCE00E5C127 /* ToggleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleView.swift; sourceTree = "<group>"; };
|
||||||
|
EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+SpacingConfig.swift"; sourceTree = "<group>"; };
|
||||||
|
EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typogprahy+Styles.swift"; sourceTree = "<group>"; };
|
||||||
|
EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+Enums.swift"; sourceTree = "<group>"; };
|
||||||
|
EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+ContentSizeCategory.swift"; sourceTree = "<group>"; };
|
||||||
|
EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Typography+Additional.swift"; sourceTree = "<group>"; };
|
||||||
|
EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSTypography.swift; sourceTree = "<group>"; };
|
||||||
|
EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RawRepresentable.swift; sourceTree = "<group>"; };
|
||||||
EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
|
EA0FC2C52914222900DF80B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
|
||||||
EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = "<group>"; };
|
EA1DA1CA2A2E36DC001C51D2 /* SelectorBase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = "<group>"; };
|
||||||
EA1F266128B945070033E859 /* RadioSwatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; };
|
EA1F266128B945070033E859 /* RadioSwatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioSwatch.swift; sourceTree = "<group>"; };
|
||||||
@ -446,6 +460,7 @@
|
|||||||
EAF7F0992899B17200B287F5 /* CATransaction.swift */,
|
EAF7F0992899B17200B287F5 /* CATransaction.swift */,
|
||||||
EA33622D2891EA3C0071C351 /* DispatchQueue+Once.swift */,
|
EA33622D2891EA3C0071C351 /* DispatchQueue+Once.swift */,
|
||||||
EABFEB632A26473700C4C106 /* NSAttributedString.swift */,
|
EABFEB632A26473700C4C106 /* NSAttributedString.swift */,
|
||||||
|
EA0D1C442A6AD73000E5C127 /* RawRepresentable.swift */,
|
||||||
EAB2376529E9952D00AABE9A /* UIApplication.swift */,
|
EAB2376529E9952D00AABE9A /* UIApplication.swift */,
|
||||||
EA3361A7288B23300071C351 /* UIColor.swift */,
|
EA3361A7288B23300071C351 /* UIColor.swift */,
|
||||||
EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */,
|
EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */,
|
||||||
@ -455,6 +470,7 @@
|
|||||||
EAD062A62A3B67770015965D /* UIView+CALayer.swift */,
|
EAD062A62A3B67770015965D /* UIView+CALayer.swift */,
|
||||||
EAB5FF0029424ACB00998C17 /* UIControl.swift */,
|
EAB5FF0029424ACB00998C17 /* UIControl.swift */,
|
||||||
EA985C662970C21600F2FF2E /* VDSLayout.swift */,
|
EA985C662970C21600F2FF2E /* VDSLayout.swift */,
|
||||||
|
EA0D1C422A6AD70900E5C127 /* VDSTypography.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -638,6 +654,11 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
EAB1D2CE28ABEF2B00DAE764 /* Typography.swift */,
|
EAB1D2CE28ABEF2B00DAE764 /* Typography.swift */,
|
||||||
|
EA0D1C402A6AD61C00E5C127 /* Typography+Additional.swift */,
|
||||||
|
EA0D1C3E2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift */,
|
||||||
|
EA0D1C3C2A6AD57600E5C127 /* Typography+Enums.swift */,
|
||||||
|
EA0D1C382A6AD4DF00E5C127 /* Typography+SpacingConfig.swift */,
|
||||||
|
EA0D1C3A2A6AD51B00E5C127 /* Typogprahy+Styles.swift */,
|
||||||
);
|
);
|
||||||
path = Typography;
|
path = Typography;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -881,7 +902,9 @@
|
|||||||
EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */,
|
EAF7F0A6289B0CE000B287F5 /* Resetable.swift in Sources */,
|
||||||
EA985C2D296F03FE00F2FF2E /* TileletIconModels.swift in Sources */,
|
EA985C2D296F03FE00F2FF2E /* TileletIconModels.swift in Sources */,
|
||||||
EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */,
|
EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */,
|
||||||
|
EA0D1C3F2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift in Sources */,
|
||||||
EA5F86C82A1BD99100BC83E4 /* TabModel.swift in Sources */,
|
EA5F86C82A1BD99100BC83E4 /* TabModel.swift in Sources */,
|
||||||
|
EA0D1C432A6AD70900E5C127 /* VDSTypography.swift in Sources */,
|
||||||
EA297A5729FB0A360031ED56 /* AppleGuidlinesTouchable.swift in Sources */,
|
EA297A5729FB0A360031ED56 /* AppleGuidlinesTouchable.swift in Sources */,
|
||||||
EA3361C328902D960071C351 /* Toggle.swift in Sources */,
|
EA3361C328902D960071C351 /* Toggle.swift in Sources */,
|
||||||
EAF7F0A0289AB7EC00B287F5 /* View.swift in Sources */,
|
EAF7F0A0289AB7EC00B287F5 /* View.swift in Sources */,
|
||||||
@ -891,6 +914,7 @@
|
|||||||
EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */,
|
EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */,
|
||||||
EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */,
|
EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */,
|
||||||
EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */,
|
EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */,
|
||||||
|
EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */,
|
||||||
EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */,
|
EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */,
|
||||||
EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */,
|
EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */,
|
||||||
EAC925832911B35400091998 /* TextLinkCaret.swift in Sources */,
|
EAC925832911B35400091998 /* TextLinkCaret.swift in Sources */,
|
||||||
@ -900,6 +924,7 @@
|
|||||||
EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */,
|
EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */,
|
||||||
EA8141102A127066004F60D2 /* UIColor+VDSColor.swift in Sources */,
|
EA8141102A127066004F60D2 /* UIColor+VDSColor.swift in Sources */,
|
||||||
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */,
|
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */,
|
||||||
|
EA0D1C412A6AD61C00E5C127 /* Typography+Additional.swift in Sources */,
|
||||||
EAC925842911C63100091998 /* Colorable.swift in Sources */,
|
EAC925842911C63100091998 /* Colorable.swift in Sources */,
|
||||||
EAB5FEF5292D371F00998C17 /* ButtonBase.swift in Sources */,
|
EAB5FEF5292D371F00998C17 /* ButtonBase.swift in Sources */,
|
||||||
EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */,
|
EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */,
|
||||||
@ -935,7 +960,9 @@
|
|||||||
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */,
|
EAF7F0B9289C139800B287F5 /* ColorConfiguration.swift in Sources */,
|
||||||
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
|
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
|
||||||
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */,
|
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */,
|
||||||
|
EA0D1C3B2A6AD51B00E5C127 /* Typogprahy+Styles.swift in Sources */,
|
||||||
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
||||||
|
EA0D1C3D2A6AD57600E5C127 /* Typography+Enums.swift in Sources */,
|
||||||
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */,
|
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */,
|
||||||
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,
|
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,
|
||||||
EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */,
|
EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */,
|
||||||
@ -966,6 +993,7 @@
|
|||||||
EA3361B6288B2A410071C351 /* Control.swift in Sources */,
|
EA3361B6288B2A410071C351 /* Control.swift in Sources */,
|
||||||
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */,
|
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */,
|
||||||
EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */,
|
EAF7F0B7289C12A600B287F5 /* UITapGestureRecognizer.swift in Sources */,
|
||||||
|
EA0D1C392A6AD4DF00E5C127 /* Typography+SpacingConfig.swift in Sources */,
|
||||||
EAB2376629E9952D00AABE9A /* UIApplication.swift in Sources */,
|
EAB2376629E9952D00AABE9A /* UIApplication.swift in Sources */,
|
||||||
EAB5FED429267EB300998C17 /* UIView.swift in Sources */,
|
EAB5FED429267EB300998C17 /* UIView.swift in Sources */,
|
||||||
EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */,
|
EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */,
|
||||||
@ -1135,7 +1163,7 @@
|
|||||||
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 28;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
@ -1172,7 +1200,7 @@
|
|||||||
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 28;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEFINES_MODULE = YES;
|
DEFINES_MODULE = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
|||||||
@ -226,6 +226,7 @@ open class SelectorItemBase<Selector: SelectorControlable>: Control, Errorable,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
label.reset()
|
label.reset()
|
||||||
|
|||||||
@ -75,6 +75,7 @@ open class Badge: View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
label.reset()
|
label.reset()
|
||||||
|
|||||||
@ -278,6 +278,7 @@ open class BadgeIndicator: View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
label.reset()
|
label.reset()
|
||||||
|
|||||||
@ -130,6 +130,7 @@ open class Button: ButtonBase, Useable {
|
|||||||
heightConstraint?.isActive = true
|
heightConstraint?.isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
use = .primary
|
use = .primary
|
||||||
|
|||||||
@ -53,6 +53,8 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
|||||||
|
|
||||||
open var attributes: [any LabelAttributeModel]? { nil }
|
open var attributes: [any LabelAttributeModel]? { nil }
|
||||||
|
|
||||||
|
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var surface: Surface = .light { didSet { setNeedsUpdate() }}
|
open var surface: Surface = .light { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var userInfo = [String: Primitive]()
|
open var userInfo = [String: Primitive]()
|
||||||
@ -134,6 +136,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open func reset() {
|
open func reset() {
|
||||||
surface = .light
|
surface = .light
|
||||||
disabled = false
|
disabled = false
|
||||||
@ -185,6 +188,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
|||||||
//create the primary string
|
//create the primary string
|
||||||
let mutableText = NSMutableAttributedString.mutableText(for: text ?? "No Text",
|
let mutableText = NSMutableAttributedString.mutableText(for: text ?? "No Text",
|
||||||
textStyle: textStyle,
|
textStyle: textStyle,
|
||||||
|
useScaledFont: useScaledFont,
|
||||||
textColor: textColor,
|
textColor: textColor,
|
||||||
alignment: titleLabel?.textAlignment ?? .center,
|
alignment: titleLabel?.textAlignment ?? .center,
|
||||||
lineBreakMode: titleLabel?.lineBreakMode ?? .byTruncatingTail)
|
lineBreakMode: titleLabel?.lineBreakMode ?? .byTruncatingTail)
|
||||||
|
|||||||
@ -87,6 +87,7 @@ open class TextLink: ButtonBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
text = nil
|
text = nil
|
||||||
|
|||||||
@ -79,6 +79,7 @@ open class TextLinkCaret: ButtonBase {
|
|||||||
accessibilityTraits = .link
|
accessibilityTraits = .link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
iconPosition = .right
|
iconPosition = .right
|
||||||
|
|||||||
@ -253,6 +253,7 @@ open class ButtonIcon: Control {
|
|||||||
iconLayoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
|
iconLayoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
kind = .ghost
|
kind = .ghost
|
||||||
|
|||||||
@ -62,6 +62,7 @@ open class Icon: View {
|
|||||||
accessibilityTraits = .image
|
accessibilityTraits = .image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
color = VDSColor.paletteBlack
|
color = VDSColor.paletteBlack
|
||||||
|
|||||||
@ -27,12 +27,16 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
|
|
||||||
open var useAttributedText: Bool = false
|
open var useAttributedText: Bool = false
|
||||||
|
|
||||||
|
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var surface: Surface = .light { didSet { setNeedsUpdate() }}
|
open var surface: Surface = .light { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var attributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() }}
|
open var attributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var textStyle: TextStyle = .defaultStyle { didSet { setNeedsUpdate() }}
|
open var textStyle: TextStyle = .defaultStyle { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
|
open var edgeInsets: UIEdgeInsets { textStyle.edgeInsets }
|
||||||
|
|
||||||
open var textPosition: TextPosition = .left { didSet { setNeedsUpdate() }}
|
open var textPosition: TextPosition = .left { didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
open var userInfo = [String: Primitive]()
|
open var userInfo = [String: Primitive]()
|
||||||
@ -87,6 +91,13 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
open func initialSetup() {
|
open func initialSetup() {
|
||||||
if !initialSetupPerformed {
|
if !initialSetupPerformed {
|
||||||
|
//register for ContentSizeChanges
|
||||||
|
NotificationCenter
|
||||||
|
.Publisher(center: .default, name: UIContentSizeCategory.didChangeNotification)
|
||||||
|
.sink { [weak self] notification in
|
||||||
|
self?.setNeedsUpdate()
|
||||||
|
}.store(in: &subscribers)
|
||||||
|
|
||||||
backgroundColor = .clear
|
backgroundColor = .clear
|
||||||
numberOfLines = 0
|
numberOfLines = 0
|
||||||
lineBreakMode = .byWordWrapping
|
lineBreakMode = .byWordWrapping
|
||||||
@ -101,6 +112,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
|
|
||||||
open func setup() {}
|
open func setup() {}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open func reset() {
|
open func reset() {
|
||||||
surface = .light
|
surface = .light
|
||||||
disabled = false
|
disabled = false
|
||||||
@ -114,6 +126,13 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
setNeedsUpdate()
|
setNeedsUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Overrides
|
||||||
|
//--------------------------------------------------
|
||||||
|
open override func drawText(in rect: CGRect) {
|
||||||
|
super.drawText(in: rect.inset(by: edgeInsets))
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Overrides
|
// MARK: - Overrides
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -134,6 +153,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
//create the primary string
|
//create the primary string
|
||||||
let mutableText = NSMutableAttributedString.mutableText(for: text,
|
let mutableText = NSMutableAttributedString.mutableText(for: text,
|
||||||
textStyle: textStyle,
|
textStyle: textStyle,
|
||||||
|
useScaledFont: useScaledFont,
|
||||||
textColor: textColorConfiguration.getColor(self),
|
textColor: textColorConfiguration.getColor(self),
|
||||||
alignment: textPosition.textAlignment,
|
alignment: textPosition.textAlignment,
|
||||||
lineBreakMode: lineBreakMode)
|
lineBreakMode: lineBreakMode)
|
||||||
@ -142,7 +162,12 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable {
|
|||||||
|
|
||||||
//set the attributed text
|
//set the attributed text
|
||||||
attributedText = mutableText
|
attributedText = mutableText
|
||||||
|
|
||||||
|
//get accessibility
|
||||||
updateAccessibilityLabel()
|
updateAccessibilityLabel()
|
||||||
|
|
||||||
|
//force a drawText
|
||||||
|
setNeedsDisplay()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,6 +40,7 @@ open class Line: View {
|
|||||||
lineView.pinToSuperView()
|
lineView.pinToSuperView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
style = .primary
|
style = .primary
|
||||||
|
|||||||
@ -228,6 +228,7 @@ open class Notification: View {
|
|||||||
subTitleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
|
subTitleLabel.textColorConfiguration = textColorConfiguration.eraseToAnyColorable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
|
|||||||
@ -200,6 +200,7 @@ open class RadioBoxItem: Control, Changeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
textLabel.reset()
|
textLabel.reset()
|
||||||
|
|||||||
@ -89,6 +89,7 @@ open class RadioSwatch: Control {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
fillImage = nil
|
fillImage = nil
|
||||||
|
|||||||
@ -228,6 +228,7 @@ open class EntryField: Control, Changeable {
|
|||||||
return containerView
|
return containerView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
titleLabel.reset()
|
titleLabel.reset()
|
||||||
|
|||||||
@ -140,6 +140,7 @@ open class InputField: EntryField, UITextFieldDelegate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
textField.text = ""
|
textField.text = ""
|
||||||
|
|||||||
@ -79,6 +79,7 @@ open class TextArea: EntryField {
|
|||||||
textView.delegate = self
|
textView.delegate = self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
textView.text = ""
|
textView.text = ""
|
||||||
|
|||||||
@ -189,6 +189,7 @@ open class TileContainer: Control {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
color = .white
|
color = .white
|
||||||
|
|||||||
@ -240,6 +240,7 @@ open class Tilelet: TileContainer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
aspectRatio = .none
|
aspectRatio = .none
|
||||||
color = .black
|
color = .black
|
||||||
|
|||||||
@ -196,6 +196,7 @@ open class TitleLockup: View {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
textPosition = .left
|
textPosition = .left
|
||||||
|
|||||||
@ -172,6 +172,7 @@ open class Toggle: Control, Changeable {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
label.reset()
|
label.reset()
|
||||||
|
|||||||
@ -136,6 +136,7 @@ open class ToggleView: Control, Changeable {
|
|||||||
|
|
||||||
open override var intrinsicContentSize: CGSize { toggleSize }
|
open override var intrinsicContentSize: CGSize { toggleSize }
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
isOn = false
|
isOn = false
|
||||||
|
|||||||
@ -139,6 +139,7 @@ open class Tooltip: Control, TooltipLaunchable {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
size = .medium
|
size = .medium
|
||||||
|
|||||||
@ -77,6 +77,7 @@ open class TrailingTooltipLabel: View, TooltipLaunchable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resets back to this objects default settings.
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
super.reset()
|
super.reset()
|
||||||
labelText = nil
|
labelText = nil
|
||||||
|
|||||||
@ -9,6 +9,10 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
extension NSAttributedString {
|
extension NSAttributedString {
|
||||||
|
|
||||||
|
/// Spacer in the form of a AttributedString.
|
||||||
|
/// - Parameter width: size of the space.
|
||||||
|
/// - Returns: AttributedString with the Space of the width you asked.
|
||||||
public static func spacer(for width: CGFloat) -> NSAttributedString {
|
public static func spacer(for width: CGFloat) -> NSAttributedString {
|
||||||
let spacerImage = UIImage()
|
let spacerImage = UIImage()
|
||||||
let spacerAttachment = NSTextAttachment()
|
let spacerAttachment = NSTextAttachment()
|
||||||
@ -19,41 +23,56 @@ extension NSAttributedString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension NSMutableAttributedString {
|
extension NSMutableAttributedString {
|
||||||
public static func mutableText(for text: String, textStyle: TextStyle, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString {
|
|
||||||
let font = textStyle.font
|
|
||||||
let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
|
|
||||||
let attributedString = NSMutableAttributedString(string: text, attributes: startingAttributes)
|
|
||||||
|
|
||||||
//get the range
|
/// This will used along with mutableText method to determine if you will use a ratio version of the lineHeight within a TextStyle if you have a scaled font being used.
|
||||||
let entireRange = NSRange(location: 0, length: attributedString.length)
|
public static var useScaledLineHeight: Bool = false
|
||||||
|
|
||||||
//set letterSpacing
|
/// Creates a MutableAttributedString for the text and other properties you have passed into the method.
|
||||||
if textStyle.letterSpacing > 0.0 {
|
/// - Parameters:
|
||||||
attributedString.addAttribute(.kern, value: textStyle.letterSpacing, range: entireRange)
|
/// - text: Text you want to draw onscreen.
|
||||||
}
|
/// - textStyle: Style of Typography you want to render the Text.
|
||||||
|
/// - useScaledFont: Determines if you used a scaledFont or a normal Font from the TextStyle.
|
||||||
|
/// - textColor: Color of Text to render.
|
||||||
|
/// - alignment: Text alignment.
|
||||||
|
/// - lineBreakMode: LineBreak Mode.
|
||||||
|
/// - Returns: MutableAttributedString from al lof the properties you passed in to help render Text using non-standard properties.
|
||||||
|
public static func mutableText(for text: String, textStyle: TextStyle, useScaledFont: Bool = true, textColor: UIColor, alignment: NSTextAlignment = .left, lineBreakMode: NSLineBreakMode) -> NSMutableAttributedString {
|
||||||
|
|
||||||
|
//var for if you can scale or not
|
||||||
|
let scaledMode = useScaledFont && TextStyle.canScaleFonts
|
||||||
|
|
||||||
|
//create the paragraph for specific properties
|
||||||
let paragraph = NSMutableParagraphStyle()
|
let paragraph = NSMutableParagraphStyle()
|
||||||
paragraph.alignment = alignment
|
paragraph.alignment = alignment
|
||||||
paragraph.lineBreakMode = lineBreakMode
|
paragraph.lineBreakMode = lineBreakMode
|
||||||
|
|
||||||
if textStyle.lineSpacing > 0 {
|
var defaultFont = textStyle.font
|
||||||
paragraph.lineSpacing = textStyle.lineSpacing
|
var lineHeight = textStyle.lineHeight
|
||||||
|
|
||||||
|
if scaledMode {
|
||||||
|
defaultFont = defaultFont.scaledFont
|
||||||
|
if useScaledLineHeight {
|
||||||
|
lineHeight = textStyle.scaledLineHeight
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//set lineHeight
|
//set lineHeight
|
||||||
if textStyle.lineHeight > 0.0 {
|
if textStyle.lineHeight > 0.0 {
|
||||||
let lineHeight = textStyle.lineHeight
|
|
||||||
// if textStyle.lineHeight > textStyle.pointSize {
|
|
||||||
paragraph.maximumLineHeight = lineHeight
|
|
||||||
paragraph.minimumLineHeight = lineHeight
|
paragraph.minimumLineHeight = lineHeight
|
||||||
// paragraph.lineHeightMultiple = lineHeight / textStyle.pointSize
|
paragraph.maximumLineHeight = lineHeight
|
||||||
// } else {
|
|
||||||
// paragraph.lineHeightMultiple = lineHeight / font.pointSize
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
attributedString.addAttribute( .baselineOffset, value: textStyle.baselineOffset, range: entireRange)
|
|
||||||
attributedString.addAttribute( .paragraphStyle, value: paragraph, range: entireRange)
|
|
||||||
|
|
||||||
return attributedString
|
//create the attributeArray
|
||||||
|
var attributes: [NSAttributedString.Key : Any] = [.font: defaultFont,
|
||||||
|
.foregroundColor: textColor,
|
||||||
|
.paragraphStyle: paragraph]
|
||||||
|
|
||||||
|
//set letterSpacing
|
||||||
|
if textStyle.letterSpacing > 0.0 {
|
||||||
|
attributes[.kern] = textStyle.letterSpacing
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSMutableAttributedString(string: text, attributes: attributes)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
VDS/Extensions/RawRepresentable.swift
Normal file
15
VDS/Extensions/RawRepresentable.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// RawRepresentable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Helper method to check to see if you exist in a collection
|
||||||
|
extension RawRepresentable where Self.RawValue: Equatable {
|
||||||
|
public func isWithin(_ collection: [Self]) -> Bool {
|
||||||
|
(collection.first(where: {$0 == self}) != nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -125,6 +125,8 @@ extension UIColor {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert your UIColor to a VDSColor
|
||||||
|
/// - Returns: VDSColor enum that matches the hexString for this UIColor
|
||||||
public func toVDSColor() -> VDSColor? {
|
public func toVDSColor() -> VDSColor? {
|
||||||
guard let hex = hexString else { return nil }
|
guard let hex = hexString else { return nil }
|
||||||
let found = VDSColor.allCases.first{ $0.uiColor.hexString == hex }
|
let found = VDSColor.allCases.first{ $0.uiColor.hexString == hex }
|
||||||
|
|||||||
@ -9,6 +9,10 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
extension UIControl.State {
|
extension UIControl.State {
|
||||||
|
|
||||||
|
/// State for Error
|
||||||
public static var error = UIControl.State(rawValue: 1 << 16)
|
public static var error = UIControl.State(rawValue: 1 << 16)
|
||||||
|
|
||||||
|
/// State for Success
|
||||||
public static var success = UIControl.State(rawValue: 1 << 17)
|
public static var success = UIControl.State(rawValue: 1 << 17)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,9 @@ extension UIView {
|
|||||||
// MARK: - CALayer
|
// MARK: - CALayer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
extension CALayer {
|
extension CALayer {
|
||||||
|
|
||||||
|
/// Removes a sublayer of a specific name.
|
||||||
|
/// - Parameter layerName: Layer with the name you want to remove.
|
||||||
public func remove(layerName: String) {
|
public func remove(layerName: String) {
|
||||||
guard let sublayers = sublayers else {
|
guard let sublayers = sublayers else {
|
||||||
return
|
return
|
||||||
@ -90,6 +93,12 @@ extension CALayer {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
|
/// Adds a border to a specific sides with the parameters.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - side: Side in which to add the border.
|
||||||
|
/// - width: Width of the border.
|
||||||
|
/// - color: Color of the border.
|
||||||
|
/// - offset: offset of the border.
|
||||||
public func addBorder(side: UIRectEdge, width: CGFloat, color: UIColor, offset: CGFloat = 0) {
|
public func addBorder(side: UIRectEdge, width: CGFloat, color: UIColor, offset: CGFloat = 0) {
|
||||||
let layerName = borderLayerName(for: side)
|
let layerName = borderLayerName(for: side)
|
||||||
layer.remove(layerName: layerName)
|
layer.remove(layerName: layerName)
|
||||||
@ -114,6 +123,7 @@ extension UIView {
|
|||||||
layer.addSublayer(borderLayer)
|
layer.addSublayer(borderLayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes all of the borders addeding using the addBorder method.
|
||||||
public func removeBorders() {
|
public func removeBorders() {
|
||||||
layer.borderWidth = 0
|
layer.borderWidth = 0
|
||||||
layer.borderColor = nil
|
layer.borderColor = nil
|
||||||
|
|||||||
@ -21,6 +21,11 @@ extension UIView {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
extension UIView {
|
extension UIView {
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Pins each to the all 4 anchor points to a view.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - view: View that you will be pinned within.
|
||||||
|
/// - edges: Insets for each side.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self {
|
public func pin(_ view: UIView, with edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self {
|
||||||
pinLeading(view.leadingAnchor, edges.left)
|
pinLeading(view.leadingAnchor, edges.left)
|
||||||
pinTrailing(view.trailingAnchor, edges.right)
|
pinTrailing(view.trailingAnchor, edges.right)
|
||||||
@ -30,6 +35,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
|
||||||
|
/// Pins each to the all 4 anchor points to the view you are set within.
|
||||||
|
/// - Parameter edges: Insets for each side.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinToSuperView(_ edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self {
|
public func pinToSuperView(_ edges: UIEdgeInsets = UIEdgeInsets.zero) -> Self {
|
||||||
if let superview {
|
if let superview {
|
||||||
pin(superview, with: edges)
|
pin(superview, with: edges)
|
||||||
@ -44,34 +53,52 @@ extension UIView {
|
|||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func height(_ constant: CGFloat) -> Self {
|
public func height(_ constant: CGFloat) -> Self {
|
||||||
height(constant: constant)
|
height(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor where the height constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func heightGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
public func heightGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
||||||
heightGreaterThanEqualTo(constant: constant)
|
heightGreaterThanEqualTo(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor where the height constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func heightLessThanEqualTo(_ constant: CGFloat) -> Self {
|
public func heightLessThanEqualTo(_ constant: CGFloat) -> Self {
|
||||||
heightLessThanEqualTo(constant: constant)
|
heightLessThanEqualTo(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func height(constant: CGFloat) -> NSLayoutConstraint {
|
public func height(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
heightAnchor.constraint(equalToConstant: constant).activate()
|
heightAnchor.constraint(equalToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor where the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func heightGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
public func heightGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
heightAnchor.constraint(greaterThanOrEqualToConstant: constant).activate()
|
heightAnchor.constraint(greaterThanOrEqualToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a heightAnchor where the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func heightLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
public func heightLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
heightAnchor.constraint(lessThanOrEqualToConstant: constant).activate()
|
heightAnchor.constraint(lessThanOrEqualToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
@ -84,34 +111,52 @@ extension UIView {
|
|||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor.
|
||||||
|
/// - Parameter constant: Width Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func width(_ constant: CGFloat) -> Self {
|
public func width(_ constant: CGFloat) -> Self {
|
||||||
width(constant: constant)
|
width(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor where the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func widthGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
public func widthGreaterThanEqualTo(_ constant: CGFloat) -> Self {
|
||||||
widthGreaterThanEqualTo(constant: constant)
|
widthGreaterThanEqualTo(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor where the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func widthLessThanEqualTo(_ constant: CGFloat) -> Self {
|
public func widthLessThanEqualTo(_ constant: CGFloat) -> Self {
|
||||||
widthLessThanEqualTo(constant: constant)
|
widthLessThanEqualTo(constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func width(constant: CGFloat) -> NSLayoutConstraint {
|
public func width(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
widthAnchor.constraint(equalToConstant: constant).activate()
|
widthAnchor.constraint(equalToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor with the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func widthGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
public func widthGreaterThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
widthAnchor.constraint(greaterThanOrEqualToConstant: constant).activate()
|
widthAnchor.constraint(greaterThanOrEqualToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a widthAnchor with the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func widthLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
public func widthLessThanEqualTo(constant: CGFloat) -> NSLayoutConstraint {
|
||||||
widthAnchor.constraint(lessThanOrEqualToConstant: constant).activate()
|
widthAnchor.constraint(lessThanOrEqualToConstant: constant).activate()
|
||||||
}
|
}
|
||||||
@ -123,29 +168,48 @@ extension UIView {
|
|||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTop(_ constant: CGFloat = 0.0) -> Self {
|
public func pinTop(_ constant: CGFloat = 0.0) -> Self {
|
||||||
return pinTop(nil, constant)
|
return pinTop(nil, constant)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor to a specific YAxisAnchor.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTop(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTop(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTop(anchor: anchor, constant: constant)
|
pinTop(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor to a specific YAxisAnchor passed in using a lessThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTopLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTopLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinBottomLessThanOrEqualTo(anchor: anchor, constant: constant)
|
pinTopLessThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor to a specific YAxisAnchor passed in using a greaterThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTopGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTopGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTopGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
pinTopGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTop(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTop(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -153,6 +217,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor with the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTopLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTopLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -160,6 +228,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a topAnchor with the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the topAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTopGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTopGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.topAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -173,29 +245,48 @@ extension UIView {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
extension UIView {
|
extension UIView {
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinBottom(_ constant: CGFloat = 0.0) -> Self {
|
public func pinBottom(_ constant: CGFloat = 0.0) -> Self {
|
||||||
return pinBottom(nil, constant)
|
return pinBottom(nil, constant)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor to a specific YAxisAnchor.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinBottom(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinBottom(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinBottom(anchor: anchor, constant: constant)
|
pinBottom(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor to a specific YAxisAnchor passed in using a lessThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinBottomLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinBottomLessThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinBottomLessThanOrEqualTo(anchor: anchor, constant: constant)
|
pinBottomLessThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor to a specific YAxisAnchor passed in using a greaterThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinBottomGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinBottomGreaterThanOrEqualTo(_ anchor: NSLayoutYAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinBottomGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
pinBottomGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinBottom(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinBottom(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -203,6 +294,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor with the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinBottomLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinBottomLessThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -210,6 +305,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a bottomAnchor with the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the bottomAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinBottomGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinBottomGreaterThanOrEqualTo(anchor: NSLayoutYAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
let found: NSLayoutYAxisAnchor? = anchor ?? superview?.bottomAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -223,29 +322,48 @@ extension UIView {
|
|||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinLeading(_ constant: CGFloat = 0.0) -> Self {
|
public func pinLeading(_ constant: CGFloat = 0.0) -> Self {
|
||||||
return pinLeading(nil, constant)
|
return pinLeading(nil, constant)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor to a specific XAxisAnchor.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor.
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinLeading(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinLeading(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinLeading(anchor: anchor, constant: constant)
|
pinLeading(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinLeadingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinLeadingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinLeadingLessThanOrEqualTo(anchor: anchor, constant: constant)
|
pinLeadingLessThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinLeadingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinLeadingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinLeadingGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
pinLeadingGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinLeading(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinLeading(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -253,6 +371,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor with the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinLeadingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinLeadingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -260,6 +382,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a leadingAnchor with the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the leadingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinLeadingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinLeadingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.leadingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -273,29 +399,48 @@ extension UIView {
|
|||||||
extension UIView {
|
extension UIView {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor.
|
||||||
|
/// - Parameter constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTrailing(_ constant: CGFloat = 0.0) -> Self {
|
public func pinTrailing(_ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTrailing(nil, constant)
|
pinTrailing(nil, constant)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor to a specific XAxisAnchor.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor.
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTrailing(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTrailing(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTrailing(anchor: anchor, constant: constant)
|
pinTrailing(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor to a specific XAxisAnchor passed in using a lessThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTrailingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTrailingLessThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTrailingLessThanOrEqualTo(anchor: anchor, constant: constant)
|
pinTrailingLessThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor to a specific XAxisAnchor passed in using a greaterThanOrEqualTo Constraint
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: Yourself.
|
||||||
public func pinTrailingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
public func pinTrailingGreaterThanOrEqualTo(_ anchor: NSLayoutXAxisAnchor? = nil, _ constant: CGFloat = 0.0) -> Self {
|
||||||
pinTrailingGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
pinTrailingGreaterThanOrEqualTo(anchor: anchor, constant: constant)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor for the constant passed into the method.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTrailing(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTrailing(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -303,6 +448,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor with the constant passed in using a lessThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTrailingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTrailingLessThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -310,6 +459,10 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Adds a trailingAnchor with the constant passed in using a greaterThanOrEqualTo Constraint.
|
||||||
|
/// - Parameter anchor:The anchor in which to attach the trailingAnchor
|
||||||
|
/// - constant: Constant size.
|
||||||
|
/// - Returns: The Constraint that was created.
|
||||||
public func pinTrailingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
public func pinTrailingGreaterThanOrEqualTo(anchor: NSLayoutXAxisAnchor?, constant: CGFloat = 0.0) -> NSLayoutConstraint? {
|
||||||
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
let found: NSLayoutXAxisAnchor? = anchor ?? superview?.trailingAnchor
|
||||||
guard let found else { return nil }
|
guard let found else { return nil }
|
||||||
@ -320,17 +473,22 @@ extension UIView {
|
|||||||
extension NSLayoutConstraint {
|
extension NSLayoutConstraint {
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Activates yourself
|
||||||
|
/// - Returns: Self
|
||||||
public func activate() -> Self{
|
public func activate() -> Self{
|
||||||
isActive = true
|
isActive = true
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
/// Deactivates yourself
|
||||||
|
/// - Returns: Self
|
||||||
public func deactivate() -> Self{
|
public func deactivate() -> Self{
|
||||||
isActive = false
|
isActive = false
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper class that holds onto all types of Contraints.
|
||||||
public class Container {
|
public class Container {
|
||||||
public var topConstraint: NSLayoutConstraint?
|
public var topConstraint: NSLayoutConstraint?
|
||||||
public var leadingConstraint: NSLayoutConstraint?
|
public var leadingConstraint: NSLayoutConstraint?
|
||||||
|
|||||||
14
VDS/Extensions/VDSTypography.swift
Normal file
14
VDS/Extensions/VDSTypography.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// VDSTypography.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDSTypographyTokens
|
||||||
|
|
||||||
|
extension VDSTypography {
|
||||||
|
public static let letterSpacingSemiWide: CGFloat = 0.25
|
||||||
|
}
|
||||||
|
|
||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
/// Enum that is matched up for the Verizon fonts.
|
||||||
public enum Font: String, FontProtocol {
|
public enum Font: String, FontProtocol {
|
||||||
case dsBold
|
case dsBold
|
||||||
case dsRegular
|
case dsRegular
|
||||||
@ -29,6 +30,7 @@ public enum Font: String, FontProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// File Extension for each of the Font enums.
|
||||||
public var fontFileExtension: String {
|
public var fontFileExtension: String {
|
||||||
return "otf"
|
return "otf"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,15 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
/// Used in Classes that require Fonts
|
||||||
public protocol FontProtocol: CaseIterable, RawRepresentable, Hashable {
|
public protocol FontProtocol: CaseIterable, RawRepresentable, Hashable {
|
||||||
var fontFileExtension: String { get }
|
var fontFileExtension: String { get }
|
||||||
var fontName: String { get }
|
var fontName: String { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FontProtocol {
|
extension FontProtocol {
|
||||||
|
|
||||||
|
/// Registers the fonts used in the VDS Framework.
|
||||||
public func register() {
|
public func register() {
|
||||||
guard let bundle = Bundle(identifier: "com.vzw.vds") else { return }
|
guard let bundle = Bundle(identifier: "com.vzw.vds") else { return }
|
||||||
Self.allCases.forEach{ font in
|
Self.allCases.forEach{ font in
|
||||||
@ -29,6 +32,8 @@ extension FontProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Registers a font from a fileLocation
|
||||||
|
/// - Parameter url: URL of the file location.
|
||||||
public static func register(from url: URL) throws {
|
public static func register(from url: URL) throws {
|
||||||
guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
|
guard let fontDataProvider = CGDataProvider(url: url as CFURL) else {
|
||||||
throw NSError(domain: "www.verizon.com", code: 123, userInfo: ["description":"Could not create font data provider for \(url)."])
|
throw NSError(domain: "www.verizon.com", code: 123, userInfo: ["description":"Could not create font data provider for \(url)."])
|
||||||
@ -40,12 +45,19 @@ extension FontProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a UIFont for the fontName and size given.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - size: Size of the font
|
||||||
|
/// - Returns: UIFont for the fontName and Size.
|
||||||
public func font(ofSize size: CGFloat) -> UIFont{
|
public func font(ofSize size: CGFloat) -> UIFont{
|
||||||
DispatchQueue.once(block: { self.register() })
|
DispatchQueue.once(block: { self.register() })
|
||||||
if let font = UIFont(name: self.fontName, size: size){
|
guard let found = UIFont(name: self.fontName, size: size) else { return .systemFont(ofSize: size) }
|
||||||
return UIFontMetrics.default.scaledFont(for: font)
|
return found
|
||||||
} else {
|
}
|
||||||
return UIFontMetrics.default.scaledFont(for: UIFont.systemFont(ofSize: size))
|
}
|
||||||
}
|
|
||||||
|
extension UIFont {
|
||||||
|
public var scaledFont: UIFont {
|
||||||
|
UIFontMetrics.default.scaledFont(for: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,8 @@ public protocol Changeable: Handlerable where Self: UIControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Changeable {
|
extension Changeable {
|
||||||
|
/// Allows the setting of a completion block against the onChangeSubscriber cancellable. This will
|
||||||
|
/// completion block will get executed against the UIControl publisher for the 'valueChange' action.
|
||||||
public var onChange: ((Self) -> ())? {
|
public var onChange: ((Self) -> ())? {
|
||||||
get { return nil }
|
get { return nil }
|
||||||
set {
|
set {
|
||||||
|
|||||||
@ -15,6 +15,8 @@ public protocol Clickable: Handlerable where Self: UIControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Clickable {
|
extension Clickable {
|
||||||
|
/// Allows the setting of a completion block against the onClickSubscriber cancellable. This will
|
||||||
|
/// completion block will get executed against the UIControl publisher for the 'touchUpInside' action.
|
||||||
public var onClick: ((Self) -> ())? {
|
public var onClick: ((Self) -> ())? {
|
||||||
get { return nil }
|
get { return nil }
|
||||||
set {
|
set {
|
||||||
|
|||||||
@ -13,6 +13,8 @@ public protocol EnumSubset<T>: RawRepresentable, CaseIterable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension EnumSubset where RawValue == T.RawValue {
|
extension EnumSubset where RawValue == T.RawValue {
|
||||||
|
|
||||||
|
/// Will either return the Generic RawRepresentable object or the defaultValue
|
||||||
public var value: T {
|
public var value: T {
|
||||||
T(rawValue: rawValue) ?? defaultValue
|
T(rawValue: rawValue) ?? defaultValue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
/// Protocol used for objects that require to show an error
|
||||||
public protocol Errorable {
|
public protocol Errorable {
|
||||||
|
|
||||||
|
/// Whether not to show the errorText
|
||||||
var showError: Bool { get set }
|
var showError: Bool { get set }
|
||||||
|
|
||||||
|
/// Text that needs to be shown if showError is true
|
||||||
var errorText: String? { get set }
|
var errorText: String? { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
/// Protocol used for a FormField object
|
||||||
public protocol FormFieldable {
|
public protocol FormFieldable {
|
||||||
|
|
||||||
|
/// Unique Id for the Form Field object within a Form
|
||||||
var inputId: String? { get set }
|
var inputId: String? { get set }
|
||||||
|
|
||||||
|
/// Value for the Form Field
|
||||||
var value: AnyHashable? { get set }
|
var value: AnyHashable? { get set }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,5 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol Resettable {
|
public protocol Resettable {
|
||||||
|
/// Called to reset back an objects default settings.
|
||||||
func reset()
|
func reset()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,4 +15,13 @@ extension UITextField {
|
|||||||
.map { _ in self.text ?? "" }
|
.map { _ in self.text ?? "" }
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var numberPublisher: AnyPublisher<NSNumber?, Never> {
|
||||||
|
publisher(for: .editingChanged)
|
||||||
|
.map { textField in
|
||||||
|
guard let text = textField.text, let foundNumber = NumberFormatter().number(from: text) else { return nil }
|
||||||
|
return foundNumber
|
||||||
|
}
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,30 @@
|
|||||||
|
1.0.34
|
||||||
|
=======
|
||||||
|
- Added new spec for Bottom Inset for TextStyle
|
||||||
|
|
||||||
|
1.0.33
|
||||||
|
=======
|
||||||
|
- Add test variable to use ratio line height or not
|
||||||
|
|
||||||
|
1.0.32
|
||||||
|
=======
|
||||||
|
- Fixed bug dealing with Scaled
|
||||||
|
- Added ability to use minimumLineheight in Paragraph for AttributedString creation
|
||||||
|
|
||||||
|
1.0.31
|
||||||
|
=======
|
||||||
|
- updated version only
|
||||||
|
|
||||||
|
1.0.30
|
||||||
|
=======
|
||||||
|
- Updated Label to allow Scaled Fonts
|
||||||
|
- Refactored Code TextStyle
|
||||||
|
|
||||||
|
1.0.29
|
||||||
|
=======
|
||||||
|
- Updated TextStyle and Label for dealing with Top/Bottom insets
|
||||||
|
- Refactored Code for Checkbox/RadioButton/Toggle
|
||||||
|
|
||||||
1.0.28
|
1.0.28
|
||||||
=======
|
=======
|
||||||
- CXTDT-423141- Tabs - Incorrect spacing on top-aligned Fill container
|
- CXTDT-423141- Tabs - Incorrect spacing on top-aligned Fill container
|
||||||
|
|||||||
270
VDS/Typography/Typogprahy+Styles.swift
Normal file
270
VDS/Typography/Typogprahy+Styles.swift
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
//
|
||||||
|
// Typogprahy+Styles.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import VDSTypographyTokens
|
||||||
|
|
||||||
|
//MARK: Definitions
|
||||||
|
extension TextStyle {
|
||||||
|
|
||||||
|
// Static properties for different text styles
|
||||||
|
public static let featureXLarge = TextStyle(rawValue: "featureXLarge",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -6: -4))
|
||||||
|
|
||||||
|
public static let boldFeatureXLarge = TextStyle(rawValue: "boldFeatureXLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -6: -4))
|
||||||
|
|
||||||
|
public static let featureLarge = TextStyle(rawValue: "featureLarge",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -6: -2))
|
||||||
|
|
||||||
|
|
||||||
|
public static let boldFeatureLarge = TextStyle(rawValue: "boldFeatureLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -6: -2))
|
||||||
|
|
||||||
|
public static let featureMedium = TextStyle(rawValue: "featureMedium",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -4: -2))
|
||||||
|
|
||||||
|
public static let boldFeatureMedium = TextStyle(rawValue: "boldFeatureMedium",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -4: -2))
|
||||||
|
|
||||||
|
public static let featureSmall = TextStyle(rawValue: "featureSmall",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let boldFeatureSmall = TextStyle(rawValue: "boldFeatureSmall",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let featureXSmall = TextStyle(rawValue: "featureXSmall",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let boldFeatureXSmall = TextStyle(rawValue: "boldFeatureXSmall",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let title2XLarge = TextStyle(rawValue: "title2XLarge",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let boldTitle2XLarge = TextStyle(rawValue: "boldTitle2XLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40,
|
||||||
|
letterSpacing: 0,
|
||||||
|
edgeInsets: .init(bottom: UIDevice.isIPad ? -2: 0))
|
||||||
|
|
||||||
|
public static let titleXLarge = TextStyle(rawValue: "titleXLarge",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
||||||
|
|
||||||
|
public static let boldTitleXLarge = TextStyle(rawValue: "boldTitleXLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let titleLarge = TextStyle(rawValue: "titleLarge",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
||||||
|
|
||||||
|
public static let boldTitleLarge = TextStyle(rawValue: "boldTitleLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let titleMedium = TextStyle(rawValue: "titleMedium",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let boldTitleMedium = TextStyle(rawValue: "boldTitleMedium",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let titleSmall = TextStyle(rawValue: "titleSmall",
|
||||||
|
fontFace: .dsLight,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let boldTitleSmall = TextStyle(rawValue: "boldTitleSmall",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16,
|
||||||
|
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let bodyLarge = TextStyle(rawValue: "bodyLarge",
|
||||||
|
fontFace: .dsRegular,
|
||||||
|
pointSize: VDSTypography.fontSizeBody16,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody20,
|
||||||
|
letterSpacing:VDSTypography.letterSpacingWide)
|
||||||
|
|
||||||
|
public static let boldBodyLarge = TextStyle(rawValue: "boldBodyLarge",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: VDSTypography.fontSizeBody16,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody20,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingWide)
|
||||||
|
|
||||||
|
public static let bodyMedium = TextStyle(rawValue: "bodyMedium",
|
||||||
|
fontFace: .dsRegular,
|
||||||
|
pointSize: VDSTypography.fontSizeBody14,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody18,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingWide)
|
||||||
|
|
||||||
|
public static let boldBodyMedium = TextStyle(rawValue: "boldBodyMedium",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: VDSTypography.fontSizeBody14,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody18,
|
||||||
|
letterSpacing: VDSTypography.letterSpacingWide)
|
||||||
|
|
||||||
|
public static let bodySmall = TextStyle(rawValue: "bodySmall",
|
||||||
|
fontFace: .dsRegular,
|
||||||
|
pointSize: VDSTypography.fontSizeBody12,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody16,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let boldBodySmall = TextStyle(rawValue: "boldBodySmall",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: VDSTypography.fontSizeBody12,
|
||||||
|
lineHeight: VDSTypography.lineHeightBody16,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let micro = TextStyle(rawValue: "micro",
|
||||||
|
fontFace: .dsRegular,
|
||||||
|
pointSize: VDSTypography.fontSizeMicro11,
|
||||||
|
lineHeight: VDSTypography.lineHeightMicro16,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static let boldMicro = TextStyle(rawValue: "boldMicro",
|
||||||
|
fontFace: .dsBold,
|
||||||
|
pointSize: VDSTypography.fontSizeMicro11,
|
||||||
|
lineHeight: VDSTypography.lineHeightMicro16,
|
||||||
|
letterSpacing: 0)
|
||||||
|
|
||||||
|
public static var allCases: [TextStyle] {
|
||||||
|
return [
|
||||||
|
featureXLarge,
|
||||||
|
boldFeatureXLarge,
|
||||||
|
featureLarge,
|
||||||
|
boldFeatureLarge,
|
||||||
|
featureMedium,
|
||||||
|
boldFeatureMedium,
|
||||||
|
featureSmall,
|
||||||
|
boldFeatureSmall,
|
||||||
|
featureXSmall,
|
||||||
|
boldFeatureXSmall,
|
||||||
|
title2XLarge,
|
||||||
|
boldTitle2XLarge,
|
||||||
|
titleXLarge,
|
||||||
|
boldTitleXLarge,
|
||||||
|
titleLarge,
|
||||||
|
boldTitleLarge,
|
||||||
|
titleMedium,
|
||||||
|
boldTitleMedium,
|
||||||
|
titleSmall,
|
||||||
|
boldTitleSmall,
|
||||||
|
bodyLarge,
|
||||||
|
boldBodyLarge,
|
||||||
|
bodyMedium,
|
||||||
|
boldBodyMedium,
|
||||||
|
bodySmall,
|
||||||
|
boldBodySmall,
|
||||||
|
micro,
|
||||||
|
boldMicro
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UIEdgeInsets {
|
||||||
|
public init(bottom: CGFloat) {
|
||||||
|
self.init(top: 0, left: 0, bottom: bottom, right: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TextStyle {
|
||||||
|
public enum StandardStyle: String, CaseIterable {
|
||||||
|
case featureXLarge,
|
||||||
|
featureLarge,
|
||||||
|
featureMedium,
|
||||||
|
featureSmall,
|
||||||
|
featureXSmall,
|
||||||
|
title2XLarge,
|
||||||
|
titleXLarge,
|
||||||
|
titleLarge,
|
||||||
|
titleMedium,
|
||||||
|
titleSmall,
|
||||||
|
bodyLarge,
|
||||||
|
bodyMedium,
|
||||||
|
bodySmall,
|
||||||
|
micro
|
||||||
|
|
||||||
|
public var bold: TextStyle {
|
||||||
|
return TextStyle(rawValue: "bold\(rawValue.prefix(1).uppercased())\(rawValue.dropFirst())")!
|
||||||
|
}
|
||||||
|
|
||||||
|
public var regular: TextStyle {
|
||||||
|
TextStyle(rawValue: rawValue)!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toStandardStyle() -> StandardStyle {
|
||||||
|
var rawName = rawValue
|
||||||
|
if rawName.hasPrefix("bold") {
|
||||||
|
let updatedRaw = rawName.replacingOccurrences(of: "bold", with: "")
|
||||||
|
rawName = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst()
|
||||||
|
}
|
||||||
|
return StandardStyle(rawValue: rawName)!
|
||||||
|
}
|
||||||
|
}
|
||||||
76
VDS/Typography/Typography+Additional.swift
Normal file
76
VDS/Typography/Typography+Additional.swift
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// Typography+Additional.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import VDSTypographyTokens
|
||||||
|
|
||||||
|
//MARK: Alignments
|
||||||
|
extension TextStyle {
|
||||||
|
|
||||||
|
/// Alignments Available for the TextStyle
|
||||||
|
public var aligments: [TextPosition] {
|
||||||
|
return [.left, .center]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: Fonts
|
||||||
|
extension TextStyle {
|
||||||
|
|
||||||
|
/// Font for the TextStyle.
|
||||||
|
public var font: UIFont {
|
||||||
|
return fontFace.font(ofSize: pointSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: Style Helper
|
||||||
|
extension TextStyle {
|
||||||
|
|
||||||
|
/// Default style used if no style is given.
|
||||||
|
public static var defaultStyle: TextStyle { return bodyLarge }
|
||||||
|
|
||||||
|
|
||||||
|
/// Find a TextStyle based off a Name.
|
||||||
|
/// - Parameter name: Name of the TextStyle you want to find.
|
||||||
|
/// - Returns: TextStyle for the given name.
|
||||||
|
public static func textStyle(for name: String) -> TextStyle? {
|
||||||
|
guard let style = TextStyle.allCases.first(where: {$0.rawValue == name }) else { return nil }
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a TextStyle based off a Font-Name and Size
|
||||||
|
/// - Parameters:
|
||||||
|
/// - fontName: Name of the font you want to find.
|
||||||
|
/// - size: PointSize of the Font you want to find.
|
||||||
|
/// - Returns: The exact TextStyle based on the FontName and Point Size.
|
||||||
|
public static func style(for fontName: String, size: CGFloat) -> TextStyle? {
|
||||||
|
//filter all styles by fontName
|
||||||
|
let styles = allCases.filter{$0.fontFace.fontName == fontName }.sorted { lhs, rhs in lhs.pointSize < rhs.pointSize }
|
||||||
|
|
||||||
|
//if there are no styles then return nil
|
||||||
|
guard styles.count > 0 else { return nil }
|
||||||
|
|
||||||
|
//if there is an exact match on a style with this pointSize then return it
|
||||||
|
if let style = styles.first(where: {$0.pointSize == size }) {
|
||||||
|
return style
|
||||||
|
|
||||||
|
} else if let largerIndex = styles.firstIndex(where: { $0.pointSize > size}) { //find the closet one to pointSize
|
||||||
|
return styles[max(largerIndex - 1, 0)]
|
||||||
|
|
||||||
|
} else { //return the last style
|
||||||
|
return styles.last!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TextStyle: CustomDebugStringConvertible {
|
||||||
|
|
||||||
|
/// Used for showing the TextStyle Properties.
|
||||||
|
public var debugDescription: String {
|
||||||
|
"Name: \(self.rawValue) FontFace: \(font.fontName) FontWeight: \(self.rawValue.hasPrefix("bold") ? "bold" : "normal") PointSize: \(font.pointSize) LetterSpacing: \(letterSpacing) LineHeight: \(lineHeight)"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
VDS/Typography/Typography+ContentSizeCategory.swift
Normal file
30
VDS/Typography/Typography+ContentSizeCategory.swift
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Typography+ContentSizeCategory.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension TextStyle {
|
||||||
|
/// Determines if the Framework can use scaled fonts for preferredContentSizeCategory
|
||||||
|
public static var allowScaledFonts: Bool = true
|
||||||
|
|
||||||
|
/// Determines is the User has changed their default preferredContentSizeCategory
|
||||||
|
public static var canScaleFonts: Bool {
|
||||||
|
UIApplication.shared.preferredContentSizeCategory != .large && allowScaledFonts
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The scaled version of the hardcode value 'lineHeight' within a TextStyle. This will only be different
|
||||||
|
/// from the original if the preferredContentSizeCategory has changed.
|
||||||
|
public var scaledLineHeight: CGFloat {
|
||||||
|
let defaultFont = font
|
||||||
|
let scaledFont = defaultFont.scaledFont
|
||||||
|
let ratio = scaledFont.pointSize / defaultFont.pointSize
|
||||||
|
let newLineHeight = (lineHeight * ratio).rounded()
|
||||||
|
return newLineHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
92
VDS/Typography/Typography+Enums.swift
Normal file
92
VDS/Typography/Typography+Enums.swift
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//
|
||||||
|
// Typography+Enums.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
//MARK: FontCategory
|
||||||
|
extension TextStyle {
|
||||||
|
|
||||||
|
/// Used in the Sample App but could be used elsewhere to allow selection of TextStyles
|
||||||
|
public enum FontCategory: String, CaseIterable {
|
||||||
|
case feature
|
||||||
|
case title
|
||||||
|
case body
|
||||||
|
case micro
|
||||||
|
|
||||||
|
public var sizes: [FontSize] {
|
||||||
|
switch self {
|
||||||
|
case .feature:
|
||||||
|
return [.xlarge, .large, .medium, .small, .xsmall]
|
||||||
|
case .title:
|
||||||
|
return [.xxlarge, .xlarge, .large, .medium, .small]
|
||||||
|
case .body:
|
||||||
|
return [.large, .medium, .small]
|
||||||
|
case .micro:
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the TextStyle for the FontSize.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - fontSize: FontSize you are looking for using this FontCategory.
|
||||||
|
/// - isBold: Whether or not the Font is bold.
|
||||||
|
/// - Returns: A TextStyle will be returned if all criteria is met, otherwise nil will be returned.
|
||||||
|
public func style(for fontSize: FontSize?, isBold: Bool = false) -> TextStyle? {
|
||||||
|
var styleName = ""
|
||||||
|
if isBold {
|
||||||
|
let newRaw = rawValue.prefix(1).description.uppercased() + rawValue.dropFirst()
|
||||||
|
styleName = "\(isBold ? "bold" : "")\(newRaw)\(fontSize?.rawValue ?? "")"
|
||||||
|
} else {
|
||||||
|
styleName = "\(rawValue)\(fontSize?.rawValue ?? "")"
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let style = TextStyle.textStyle(for: styleName) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the TextStyle for the specific FontCategory and FontSize.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - category: FontCategory you are looking for in the TextStyle
|
||||||
|
/// - fontSize: FontSize you are looking for using the given FontCategory.
|
||||||
|
/// - isBold: Whether or not the Font is bold.
|
||||||
|
/// - Returns: A TextStyle will be returned if all criteria is met, otherwise nil will be returned.
|
||||||
|
public func style(for category: FontCategory, with size: FontSize, isBold: Bool) -> TextStyle? {
|
||||||
|
category.style(for: size, isBold: isBold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: FontSize
|
||||||
|
extension TextStyle {
|
||||||
|
public enum FontSize: String, CaseIterable {
|
||||||
|
case xxlarge = "2XLarge"
|
||||||
|
case xlarge = "XLarge"
|
||||||
|
case large = "Large"
|
||||||
|
case medium = "Medium"
|
||||||
|
case small = "Small"
|
||||||
|
case xsmall = "XSmall"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum TextPosition: String, CaseIterable {
|
||||||
|
case left, right, center
|
||||||
|
|
||||||
|
var textAlignment: NSTextAlignment {
|
||||||
|
switch self {
|
||||||
|
case .left:
|
||||||
|
return NSTextAlignment.left
|
||||||
|
case .right:
|
||||||
|
return NSTextAlignment.right
|
||||||
|
case .center:
|
||||||
|
return NSTextAlignment.center
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
44
VDS/Typography/Typography+SpacingConfig.swift
Normal file
44
VDS/Typography/Typography+SpacingConfig.swift
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Typography+Spacing.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 7/21/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension TextStyle {
|
||||||
|
public struct SpacingConfig {
|
||||||
|
public var defaultSpacing: CGFloat = 8.0
|
||||||
|
public var configs: [TextStyle.DeviceSpacingConfig]
|
||||||
|
|
||||||
|
public func spacing(for style: TextStyle, neighboring: TextStyle) -> CGFloat {
|
||||||
|
let deviceType: TextStyle.DeviceSpacingConfig.DeviceType = UIDevice.isIPad ? .iPad : .iPhone
|
||||||
|
if let config = configs.first(where:
|
||||||
|
{ style.isWithin($0.primaryStyles) && neighboring.isWithin($0.neighboringStyles) &&
|
||||||
|
($0.deviceType == deviceType || $0.deviceType == .all )})
|
||||||
|
{
|
||||||
|
return config.spacing
|
||||||
|
}
|
||||||
|
return defaultSpacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DeviceSpacingConfig {
|
||||||
|
public enum DeviceType {
|
||||||
|
case iPhone, iPad, all
|
||||||
|
}
|
||||||
|
public var spacing: CGFloat
|
||||||
|
public var deviceType: DeviceType = .iPhone
|
||||||
|
public var primaryStyles: [TextStyle]
|
||||||
|
public var neighboringStyles: [TextStyle]
|
||||||
|
|
||||||
|
public init(_ primaryStyles: [TextStyle], neighboring: [TextStyle], spacing: CGFloat, deviceType: DeviceType = .iPhone) {
|
||||||
|
self.spacing = spacing
|
||||||
|
self.primaryStyles = primaryStyles
|
||||||
|
self.neighboringStyles = neighboring
|
||||||
|
self.deviceType = deviceType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,29 +8,15 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import VDSTypographyTokens
|
import VDSTypographyTokens
|
||||||
|
|
||||||
public enum TextPosition: String, CaseIterable {
|
|
||||||
case left, right, center
|
|
||||||
|
|
||||||
var textAlignment: NSTextAlignment {
|
|
||||||
switch self {
|
|
||||||
case .left:
|
|
||||||
return NSTextAlignment.left
|
|
||||||
case .right:
|
|
||||||
return NSTextAlignment.right
|
|
||||||
case .center:
|
|
||||||
return NSTextAlignment.center
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// This is the Definition that will determine how the Text is drawn
|
||||||
public struct TextStyle: Equatable, RawRepresentable {
|
public struct TextStyle: Equatable, RawRepresentable {
|
||||||
public let rawValue: String
|
public let rawValue: String
|
||||||
public let pointSize: CGFloat
|
public let pointSize: CGFloat
|
||||||
public let lineHeight: CGFloat
|
public let lineHeight: CGFloat
|
||||||
public let letterSpacing: CGFloat
|
public let letterSpacing: CGFloat
|
||||||
public let fontFace: Font
|
public let fontFace: Font
|
||||||
public let lineSpacing: CGFloat
|
public let edgeInsets: UIEdgeInsets
|
||||||
public let baselineOffset: CGFloat
|
|
||||||
|
|
||||||
public init?(rawValue: String) {
|
public init?(rawValue: String) {
|
||||||
guard let style = TextStyle.textStyle(for: rawValue) else { return nil }
|
guard let style = TextStyle.textStyle(for: rawValue) else { return nil }
|
||||||
@ -39,408 +25,19 @@ public struct TextStyle: Equatable, RawRepresentable {
|
|||||||
self.lineHeight = style.lineHeight
|
self.lineHeight = style.lineHeight
|
||||||
self.letterSpacing = style.letterSpacing
|
self.letterSpacing = style.letterSpacing
|
||||||
self.fontFace = style.fontFace
|
self.fontFace = style.fontFace
|
||||||
self.lineSpacing = style.lineSpacing
|
self.edgeInsets = style.edgeInsets
|
||||||
self.baselineOffset = style.baselineOffset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(rawValue: String, fontFace: Font, pointSize: CGFloat = 0.0, lineHeight: CGFloat = 0.0, letterSpacing: CGFloat = 0.0, lineSpacing: CGFloat = 0.0, baselineOffset: CGFloat = 0.0) {
|
public init(rawValue: String, fontFace: Font, pointSize: CGFloat = 0.0, lineHeight: CGFloat = 0.0, letterSpacing: CGFloat = 0.0, edgeInsets: UIEdgeInsets = .zero) {
|
||||||
self.rawValue = rawValue
|
self.rawValue = rawValue
|
||||||
self.fontFace = fontFace
|
self.fontFace = fontFace
|
||||||
self.pointSize = pointSize
|
self.pointSize = pointSize
|
||||||
self.lineHeight = lineHeight
|
self.lineHeight = lineHeight
|
||||||
self.letterSpacing = letterSpacing
|
self.letterSpacing = letterSpacing
|
||||||
self.lineSpacing = lineSpacing
|
self.edgeInsets = edgeInsets
|
||||||
self.baselineOffset = baselineOffset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var isBold: Bool {
|
public var isBold: Bool {
|
||||||
rawValue.hasPrefix("bold")
|
rawValue.hasPrefix("bold")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension VDSTypography {
|
|
||||||
public static let letterSpacingSemiWide: CGFloat = 0.25
|
|
||||||
}
|
|
||||||
//MARK: Definitions
|
|
||||||
extension TextStyle {
|
|
||||||
|
|
||||||
// Static properties for different text styles
|
|
||||||
public static let featureXLarge = TextStyle(rawValue: "featureXLarge",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldFeatureXLarge = TextStyle(rawValue: "boldFeatureXLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature144 : VDSTypography.fontSizeFeature96,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature136 : VDSTypography.lineHeightFeature88,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let featureLarge = TextStyle(rawValue: "featureLarge",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldFeatureLarge = TextStyle(rawValue: "boldFeatureLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature128 : VDSTypography.fontSizeFeature80,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature120 : VDSTypography.lineHeightFeature76,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let featureMedium = TextStyle(rawValue: "featureMedium",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldFeatureMedium = TextStyle(rawValue: "boldFeatureMedium",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature96 : VDSTypography.fontSizeFeature64,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature88 : VDSTypography.lineHeightFeature64,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let featureSmall = TextStyle(rawValue: "featureSmall",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldFeatureSmall = TextStyle(rawValue: "boldFeatureSmall",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature80 : VDSTypography.fontSizeFeature48,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature76 : VDSTypography.lineHeightFeature48,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let featureXSmall = TextStyle(rawValue: "featureXSmall",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldFeatureXSmall = TextStyle(rawValue: "boldFeatureXSmall",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeFeature64 : VDSTypography.fontSizeFeature40,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightFeature64 : VDSTypography.lineHeightFeature40,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let title2XLarge = TextStyle(rawValue: "title2XLarge",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldTitle2XLarge = TextStyle(rawValue: "boldTitle2XLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle64 : VDSTypography.fontSizeTitle40,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle64 : VDSTypography.lineHeightTitle40,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let titleXLarge = TextStyle(rawValue: "titleXLarge",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldTitleXLarge = TextStyle(rawValue: "boldTitleXLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle48 : VDSTypography.fontSizeTitle32,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle48 : VDSTypography.lineHeightTitle36,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let titleLarge = TextStyle(rawValue: "titleLarge",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingSemiWide)
|
|
||||||
|
|
||||||
public static let boldTitleLarge = TextStyle(rawValue: "boldTitleLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle32 : VDSTypography.fontSizeTitle24,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle36 : VDSTypography.lineHeightTitle28,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let titleMedium = TextStyle(rawValue: "titleMedium",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let boldTitleMedium = TextStyle(rawValue: "boldTitleMedium",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle24 : VDSTypography.fontSizeTitle20,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle28 : VDSTypography.lineHeightTitle24,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let titleSmall = TextStyle(rawValue: "titleSmall",
|
|
||||||
fontFace: .dsLight,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let boldTitleSmall = TextStyle(rawValue: "boldTitleSmall",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: UIDevice.isIPad ? VDSTypography.fontSizeTitle20 : VDSTypography.fontSizeTitle16,
|
|
||||||
lineHeight: UIDevice.isIPad ? VDSTypography.lineHeightTitle24 : VDSTypography.lineHeightTitle20,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let bodyLarge = TextStyle(rawValue: "bodyLarge",
|
|
||||||
fontFace: .dsRegular,
|
|
||||||
pointSize: VDSTypography.fontSizeBody16,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody20,
|
|
||||||
letterSpacing:VDSTypography.letterSpacingWide)
|
|
||||||
|
|
||||||
public static let boldBodyLarge = TextStyle(rawValue: "boldBodyLarge",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: VDSTypography.fontSizeBody16,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody20,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingWide)
|
|
||||||
|
|
||||||
public static let bodyMedium = TextStyle(rawValue: "bodyMedium",
|
|
||||||
fontFace: .dsRegular,
|
|
||||||
pointSize: VDSTypography.fontSizeBody14,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody18,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingWide)
|
|
||||||
|
|
||||||
public static let boldBodyMedium = TextStyle(rawValue: "boldBodyMedium",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: VDSTypography.fontSizeBody14,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody18,
|
|
||||||
letterSpacing: VDSTypography.letterSpacingWide)
|
|
||||||
|
|
||||||
public static let bodySmall = TextStyle(rawValue: "bodySmall",
|
|
||||||
fontFace: .dsRegular,
|
|
||||||
pointSize: VDSTypography.fontSizeBody12,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody16,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let boldBodySmall = TextStyle(rawValue: "boldBodySmall",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: VDSTypography.fontSizeBody12,
|
|
||||||
lineHeight: VDSTypography.lineHeightBody16,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let micro = TextStyle(rawValue: "micro",
|
|
||||||
fontFace: .dsRegular,
|
|
||||||
pointSize: VDSTypography.fontSizeMicro11,
|
|
||||||
lineHeight: VDSTypography.lineHeightMicro16,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static let boldMicro = TextStyle(rawValue: "boldMicro",
|
|
||||||
fontFace: .dsBold,
|
|
||||||
pointSize: VDSTypography.fontSizeMicro11,
|
|
||||||
lineHeight: VDSTypography.lineHeightMicro16,
|
|
||||||
letterSpacing: 0)
|
|
||||||
|
|
||||||
public static var allCases: [TextStyle] {
|
|
||||||
return [
|
|
||||||
featureXLarge,
|
|
||||||
boldFeatureXLarge,
|
|
||||||
featureLarge,
|
|
||||||
boldFeatureLarge,
|
|
||||||
featureMedium,
|
|
||||||
boldFeatureMedium,
|
|
||||||
featureSmall,
|
|
||||||
boldFeatureSmall,
|
|
||||||
featureXSmall,
|
|
||||||
boldFeatureXSmall,
|
|
||||||
title2XLarge,
|
|
||||||
boldTitle2XLarge,
|
|
||||||
titleXLarge,
|
|
||||||
boldTitleXLarge,
|
|
||||||
titleLarge,
|
|
||||||
boldTitleLarge,
|
|
||||||
titleMedium,
|
|
||||||
boldTitleMedium,
|
|
||||||
titleSmall,
|
|
||||||
boldTitleSmall,
|
|
||||||
bodyLarge,
|
|
||||||
boldBodyLarge,
|
|
||||||
bodyMedium,
|
|
||||||
boldBodyMedium,
|
|
||||||
bodySmall,
|
|
||||||
boldBodySmall,
|
|
||||||
micro,
|
|
||||||
boldMicro
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TextStyle {
|
|
||||||
public enum StandardStyle: String, CaseIterable {
|
|
||||||
case featureXLarge,
|
|
||||||
featureLarge,
|
|
||||||
featureMedium,
|
|
||||||
featureSmall,
|
|
||||||
featureXSmall,
|
|
||||||
title2XLarge,
|
|
||||||
titleXLarge,
|
|
||||||
titleLarge,
|
|
||||||
titleMedium,
|
|
||||||
titleSmall,
|
|
||||||
bodyLarge,
|
|
||||||
bodyMedium,
|
|
||||||
bodySmall,
|
|
||||||
micro
|
|
||||||
|
|
||||||
public var bold: TextStyle {
|
|
||||||
return TextStyle(rawValue: "bold\(rawValue.prefix(1).uppercased())\(rawValue.dropFirst())")!
|
|
||||||
}
|
|
||||||
|
|
||||||
public var regular: TextStyle {
|
|
||||||
TextStyle(rawValue: rawValue)!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func toStandardStyle() -> StandardStyle {
|
|
||||||
var rawName = rawValue
|
|
||||||
if rawName.hasPrefix("bold") {
|
|
||||||
let updatedRaw = rawName.replacingOccurrences(of: "bold", with: "")
|
|
||||||
rawName = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst()
|
|
||||||
}
|
|
||||||
return StandardStyle(rawValue: rawName)!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: FontCategory
|
|
||||||
extension TextStyle {
|
|
||||||
public enum FontCategory: String, CaseIterable {
|
|
||||||
case feature
|
|
||||||
case title
|
|
||||||
case body
|
|
||||||
case micro
|
|
||||||
|
|
||||||
public var sizes: [FontSize] {
|
|
||||||
switch self {
|
|
||||||
case .feature:
|
|
||||||
return [.xlarge, .large, .medium, .small, .xsmall]
|
|
||||||
case .title:
|
|
||||||
return [.xxlarge, .xlarge, .large, .medium, .small]
|
|
||||||
case .body:
|
|
||||||
return [.large, .medium, .small]
|
|
||||||
case .micro:
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func style(for fontSize: FontSize?, isBold: Bool = false) -> TextStyle? {
|
|
||||||
var styleName = ""
|
|
||||||
if isBold {
|
|
||||||
let newRaw = rawValue.prefix(1).description.uppercased() + rawValue.dropFirst()
|
|
||||||
styleName = "\(isBold ? "bold" : "")\(newRaw)\(fontSize?.rawValue ?? "")"
|
|
||||||
} else {
|
|
||||||
styleName = "\(rawValue)\(fontSize?.rawValue ?? "")"
|
|
||||||
}
|
|
||||||
|
|
||||||
guard let style = TextStyle.textStyle(for: styleName) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: FontSize
|
|
||||||
extension TextStyle {
|
|
||||||
public enum FontSize: String, CaseIterable {
|
|
||||||
case xxlarge = "2XLarge"
|
|
||||||
case xlarge = "XLarge"
|
|
||||||
case large = "Large"
|
|
||||||
case medium = "Medium"
|
|
||||||
case small = "Small"
|
|
||||||
case xsmall = "XSmall"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: Alignments
|
|
||||||
extension TextStyle {
|
|
||||||
public var aligments: [TextPosition] {
|
|
||||||
return [.left, .center]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//MARK: Fonts
|
|
||||||
extension TextStyle {
|
|
||||||
public var font: UIFont {
|
|
||||||
return fontFace.font(ofSize: pointSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TextStyle {
|
|
||||||
public static func style(for fontName: String, size: CGFloat) -> TextStyle? {
|
|
||||||
//filter all styles by fontName
|
|
||||||
let styles = allCases.filter{$0.fontFace.fontName == fontName }.sorted { lhs, rhs in lhs.pointSize < rhs.pointSize }
|
|
||||||
|
|
||||||
//if there are no styles then return nil
|
|
||||||
guard styles.count > 0 else { return nil }
|
|
||||||
|
|
||||||
//if there is an exact match on a style with this pointSize then return it
|
|
||||||
if let style = styles.first(where: {$0.pointSize == size }) {
|
|
||||||
return style
|
|
||||||
|
|
||||||
} else if let largerIndex = styles.firstIndex(where: { $0.pointSize > size}) { //find the closet one to pointSize
|
|
||||||
return styles[max(largerIndex - 1, 0)]
|
|
||||||
|
|
||||||
} else { //return the last style
|
|
||||||
return styles.last!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension RawRepresentable where Self.RawValue: Equatable {
|
|
||||||
public func isWithin(_ collection: [Self]) -> Bool {
|
|
||||||
(collection.first(where: {$0 == self}) != nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TextStyle {
|
|
||||||
public struct SpacingConfig {
|
|
||||||
public var defaultSpacing: CGFloat = 8.0
|
|
||||||
public var configs: [TextStyle.DeviceSpacingConfig]
|
|
||||||
|
|
||||||
public func spacing(for style: TextStyle, neighboring: TextStyle) -> CGFloat {
|
|
||||||
let deviceType: TextStyle.DeviceSpacingConfig.DeviceType = UIDevice.isIPad ? .iPad : .iPhone
|
|
||||||
if let config = configs.first(where:
|
|
||||||
{ style.isWithin($0.primaryStyles) && neighboring.isWithin($0.neighboringStyles) &&
|
|
||||||
($0.deviceType == deviceType || $0.deviceType == .all )})
|
|
||||||
{
|
|
||||||
return config.spacing
|
|
||||||
}
|
|
||||||
return defaultSpacing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct DeviceSpacingConfig {
|
|
||||||
public enum DeviceType {
|
|
||||||
case iPhone, iPad, all
|
|
||||||
}
|
|
||||||
public var spacing: CGFloat
|
|
||||||
public var deviceType: DeviceType = .iPhone
|
|
||||||
public var primaryStyles: [TextStyle]
|
|
||||||
public var neighboringStyles: [TextStyle]
|
|
||||||
|
|
||||||
public init(_ primaryStyles: [TextStyle], neighboring: [TextStyle], spacing: CGFloat, deviceType: DeviceType = .iPhone) {
|
|
||||||
self.spacing = spacing
|
|
||||||
self.primaryStyles = primaryStyles
|
|
||||||
self.neighboringStyles = neighboring
|
|
||||||
self.deviceType = deviceType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TextStyle: CustomDebugStringConvertible {
|
|
||||||
public var debugDescription: String {
|
|
||||||
"Name: \(self.rawValue) FontFace: \(font.fontName) FontWeight: \(self.rawValue.hasPrefix("bold") ? "bold" : "normal") PointSize: \(font.pointSize) LetterSpacing: \(letterSpacing) LineHeight: \(lineHeight)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TextStyle {
|
|
||||||
public static var defaultStyle: TextStyle { return bodyLarge }
|
|
||||||
|
|
||||||
public static func textStyle(for name: String) -> TextStyle? {
|
|
||||||
guard let style = TextStyle.allCases.first(where: {$0.rawValue == name }) else { return nil }
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user