diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index 54f32f8f..b71c30a5 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -12,7 +12,24 @@ import Combine @objc(VDSControl) /// Base Class use to build Controls. open class Control: UIControl, ViewProtocol, UserInfoable, Clickable { - + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + initialSetup() + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + //-------------------------------------------------- // MARK: - Combine Properties //-------------------------------------------------- @@ -27,10 +44,13 @@ open class Control: UIControl, ViewProtocol, UserInfoable, Clickable { } //-------------------------------------------------- - // MARK: - Properties + // MARK: - Private Properties //-------------------------------------------------- private var initialSetupPerformed = false + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- open var shouldUpdateView: Bool = true open var userInfo = [String: Primitive]() @@ -73,28 +93,9 @@ open class Control: UIControl, ViewProtocol, UserInfoable, Clickable { } } - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - initialSetup() - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - initialSetup() - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - initialSetup() - } - //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- - open func initialSetup() { if !initialSetupPerformed { initialSetupPerformed = true @@ -135,7 +136,6 @@ open class Control: UIControl, ViewProtocol, UserInfoable, Clickable { //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- - /// Implement accessibilityActivate on an element in order to handle the default action. /// - Returns: Based on whether the userInteraction is enabled. override open func accessibilityActivate() -> Bool { diff --git a/VDS/Classes/SelectorBase.swift b/VDS/Classes/SelectorBase.swift index 7daa1802..5ca0a83e 100644 --- a/VDS/Classes/SelectorBase.swift +++ b/VDS/Classes/SelectorBase.swift @@ -74,7 +74,22 @@ open class SelectorBase: Control, SelectorControlable { // MARK: - Constraints //-------------------------------------------------- internal var shapeLayer: CAShapeLayer? - + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- diff --git a/VDS/Classes/SelectorGroupHandlerBase.swift b/VDS/Classes/SelectorGroupHandlerBase.swift index 2caba743..e1a1ad38 100644 --- a/VDS/Classes/SelectorGroupHandlerBase.swift +++ b/VDS/Classes/SelectorGroupHandlerBase.swift @@ -15,7 +15,6 @@ open class SelectorGroupHandlerBase: Control, Changeable { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- - /// Array of the HandlerType registered. open var selectorViews: [HandlerType] = [] @@ -27,6 +26,7 @@ open class SelectorGroupHandlerBase: Control, Changeable { } } + /// Whether the Control is enabled or not. override open var isEnabled: Bool { didSet { selectorViews.forEach { $0.isEnabled = isEnabled } @@ -45,7 +45,6 @@ open class SelectorGroupHandlerBase: Control, Changeable { //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- - /// Handler for the Group to override on a select event. /// - Parameter selectedControl: Selected Control the user interacted. open func didSelect(_ selectedControl: HandlerType) { diff --git a/VDS/Classes/SelectorItemBase.swift b/VDS/Classes/SelectorItemBase.swift index cdb17158..92cbee77 100644 --- a/VDS/Classes/SelectorItemBase.swift +++ b/VDS/Classes/SelectorItemBase.swift @@ -156,7 +156,7 @@ open class SelectorItemBase: Control, Errorable, open var value: AnyHashable? { didSet { setNeedsUpdate() }} //-------------------------------------------------- - // MARK: - Lifecycle + // MARK: - Overrides //-------------------------------------------------- /// Executed on initialization for this View. open override func initialSetup() { @@ -229,7 +229,10 @@ open class SelectorItemBase: Control, Errorable, setNeedsUpdate() } - /// Update all labels with Text as well as adding and removing the labels. + //-------------------------------------------------- + // MARK: - Private Methods + //-------------------------------------------------- + /// Update all labels with Text as well as adding and removing the labels. func updateLabels() { //deal with labels diff --git a/VDS/Classes/SelfSizingCollectionView.swift b/VDS/Classes/SelfSizingCollectionView.swift index e5d1948d..ab81178a 100644 --- a/VDS/Classes/SelfSizingCollectionView.swift +++ b/VDS/Classes/SelfSizingCollectionView.swift @@ -12,8 +12,6 @@ import UIKit /// UICollectionView subclassed used to deal with Changing the size of itself based on its children and layout and changes of its contentSize. public final class SelfSizingCollectionView: UICollectionView { - private var contentSizeObservation: NSKeyValueObservation? - //-------------------------------------------------- // MARK: - Initialization //-------------------------------------------------- @@ -31,11 +29,15 @@ public final class SelfSizingCollectionView: UICollectionView { super.init(coder: coder) self.setupContentSizeObservation() } + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var contentSizeObservation: NSKeyValueObservation? //-------------------------------------------------- - // MARK: - UIView + // MARK: - Overrides //-------------------------------------------------- - /// The natural size for the receiving view, considering only properties of the view itself. public override var intrinsicContentSize: CGSize { let contentSize = self.contentSize @@ -55,9 +57,8 @@ public final class SelfSizingCollectionView: UICollectionView { } //-------------------------------------------------- - // MARK: - Private + // MARK: - Private Methods //-------------------------------------------------- - private func setupContentSizeObservation() { // Observing the value of contentSize seems to be the only reliable way to get the contentSize after the collection view lays out its subviews. self.contentSizeObservation = self.observe(\.contentSize, options: [.old, .new]) { [weak self] _, change in diff --git a/VDS/Classes/View.swift b/VDS/Classes/View.swift index 8f3a3e8b..6d72720a 100644 --- a/VDS/Classes/View.swift +++ b/VDS/Classes/View.swift @@ -13,25 +13,6 @@ import Combine /// Base Class used to build Views. open class View: UIView, ViewProtocol, UserInfoable { - //-------------------------------------------------- - // MARK: - Combine Properties - //-------------------------------------------------- - open var subscribers = Set() - - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- - private var initialSetupPerformed = false - - open var shouldUpdateView: Bool = true - - /// Dictionary for keeping information for this Control use only Primitives. - open var userInfo = [String: Primitive]() - - open var surface: Surface = .light { didSet { setNeedsUpdate() } } - - open var isEnabled: Bool = true { didSet { setNeedsUpdate() } } - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -50,6 +31,28 @@ open class View: UIView, ViewProtocol, UserInfoable { initialSetup() } + //-------------------------------------------------- + // MARK: - Combine Properties + //-------------------------------------------------- + open var subscribers = Set() + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var initialSetupPerformed = false + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + open var shouldUpdateView: Bool = true + + /// Dictionary for keeping information for this Control use only Primitives. + open var userInfo = [String: Primitive]() + + open var surface: Surface = .light { didSet { setNeedsUpdate() } } + + open var isEnabled: Bool = true { didSet { setNeedsUpdate() } } + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index b34dfc04..d0333a09 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -18,6 +18,22 @@ import Combine /// to its parent this object will stretch to the parent's width. @objc(VDSBadge) open class Badge: View { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- @@ -28,7 +44,6 @@ open class Badge: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- - /// Label used to render text open var label = Label().with { $0.lineBreakMode = .byTruncatingTail diff --git a/VDS/Components/BadgeIndicator/BadgeIndicator.swift b/VDS/Components/BadgeIndicator/BadgeIndicator.swift index 729a62c6..d368df96 100644 --- a/VDS/Components/BadgeIndicator/BadgeIndicator.swift +++ b/VDS/Components/BadgeIndicator/BadgeIndicator.swift @@ -15,10 +15,25 @@ import VDSTypographyTokens /// A badge indicator is a visual label used to convey status or highlight supplemental information. @objc(VDSBadgeIndicator) open class BadgeIndicator: View { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- - /// Enum type for fill color. public enum FillColor: String, CaseIterable { case red, yellow, green, orange, blue, gray, grayLowContrast, black, white @@ -119,7 +134,6 @@ open class BadgeIndicator: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- - /// Label used for the numeric kind. open var label = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) @@ -248,7 +262,7 @@ open class BadgeIndicator: View { private var textColorConfiguration = ViewColorConfiguration() //-------------------------------------------------- - // MARK: - Lifecycle + // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { @@ -328,6 +342,51 @@ open class BadgeIndicator: View { layoutIfNeeded() } + open override func layoutSubviews() { + super.layoutSubviews() + + //update the cornerRadius + badgeView.layer.cornerRadius = badgeView.frame.size.height / 2 + layer.cornerRadius = frame.size.height / 2 + + //border + if hideBorder { + layer.borderWidth = 0 + } else { + layer.borderWidth = borderWidth + layer.borderColor = borderColorConfiguration.getColor(surface).cgColor + } + + //dot + badgeView.layer.remove(layerName: "dot") + if kind == .simple && !hideDot { + //frame for the dot to sit inside + let frame = badgeView.frame + + //default calculation if a dotSize isn't given + let dotSizeRatio = frame.height * dotRatio + var dot: CGFloat = dotSizeRatio < minDotSize ? minDotSize : dotSizeRatio + if let dotSize, dotSize < frame.width, dotSize < frame.height { + dot = dotSize + } + + //get the center of the frame + let centerX = (frame.width - dot) / 2.0 + let centerY = (frame.height - dot) / 2.0 + + //create the layer to draw the dot + let dotLayer = CAShapeLayer() + dotLayer.name = "dot" + dotLayer.frame = .init(x: centerX, y: centerY, width: dot, height: dot) + dotLayer.path = UIBezierPath(ovalIn: .init(origin: .zero, size: .init(width: dot, height: dot))).cgPath + dotLayer.fillColor = textColorConfiguration.getColor(self).cgColor + badgeView.layer.addSublayer(dotLayer) + } + } + + //-------------------------------------------------- + // MARK: - Private Methods + //-------------------------------------------------- private func updateTextColorConfig() { textColorConfiguration.reset() @@ -381,49 +440,4 @@ open class BadgeIndicator: View { return min(number, maxNumber) } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- - - open override func layoutSubviews() { - super.layoutSubviews() - - //update the cornerRadius - badgeView.layer.cornerRadius = badgeView.frame.size.height / 2 - layer.cornerRadius = frame.size.height / 2 - - //border - if hideBorder { - layer.borderWidth = 0 - } else { - layer.borderWidth = borderWidth - layer.borderColor = borderColorConfiguration.getColor(surface).cgColor - } - - //dot - badgeView.layer.remove(layerName: "dot") - if kind == .simple && !hideDot { - //frame for the dot to sit inside - let frame = badgeView.frame - - //default calculation if a dotSize isn't given - let dotSizeRatio = frame.height * dotRatio - var dot: CGFloat = dotSizeRatio < minDotSize ? minDotSize : dotSizeRatio - if let dotSize, dotSize < frame.width, dotSize < frame.height { - dot = dotSize - } - - //get the center of the frame - let centerX = (frame.width - dot) / 2.0 - let centerY = (frame.height - dot) / 2.0 - - //create the layer to draw the dot - let dotLayer = CAShapeLayer() - dotLayer.name = "dot" - dotLayer.frame = .init(x: centerX, y: centerY, width: dot, height: dot) - dotLayer.path = UIBezierPath(ovalIn: .init(origin: .zero, size: .init(width: dot, height: dot))).cgPath - dotLayer.fillColor = textColorConfiguration.getColor(self).cgColor - badgeView.layer.addSublayer(dotLayer) - } - } } diff --git a/VDS/Components/Buttons/Button/Button.swift b/VDS/Components/Buttons/Button/Button.swift index 7a01cdc4..33dda940 100644 --- a/VDS/Components/Buttons/Button/Button.swift +++ b/VDS/Components/Buttons/Button/Button.swift @@ -24,6 +24,21 @@ public enum ButtonSize: String, CaseIterable { @objc(VDSButton) open class Button: ButtonBase, Useable { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -68,7 +83,6 @@ open class Button: ButtonBase, Useable { //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- - // Background Color Config private var primaryBackgroundColorConfiguration = ControlColorConfiguration().with { $0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .normal) @@ -117,22 +131,7 @@ open class Button: ButtonBase, Useable { } //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - //-------------------------------------------------- - // MARK: - Public Methods + // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { @@ -152,20 +151,6 @@ open class Button: ButtonBase, Useable { setNeedsUpdate() } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- - /// The natural size for the receiving view, considering only properties of the view itself. - open override var intrinsicContentSize: CGSize { - guard let width, width > 0 else { - var superSize = super.intrinsicContentSize - superSize.height = size.height - return superSize - } - - return CGSize(width: width > size.minimumWidth ? width : size.minimumWidth, height: size.height) - } - /// Used to make changes to the View based off a change events or from local properties. open override func updateView() { super.updateView() @@ -184,6 +169,17 @@ open class Button: ButtonBase, Useable { invalidateIntrinsicContentSize() } + + /// The natural size for the receiving view, considering only properties of the view itself. + open override var intrinsicContentSize: CGSize { + guard let width, width > 0 else { + var superSize = super.intrinsicContentSize + superSize.height = size.height + return superSize + } + + return CGSize(width: width > size.minimumWidth ? width : size.minimumWidth, height: size.height) + } } internal extension ButtonSize { diff --git a/VDS/Components/Buttons/Button/ButtonBase.swift b/VDS/Components/Buttons/Button/ButtonBase.swift index 92d5dca9..dd686efb 100644 --- a/VDS/Components/Buttons/Button/ButtonBase.swift +++ b/VDS/Components/Buttons/Button/ButtonBase.swift @@ -26,6 +26,24 @@ public protocol Buttonable: UIControl, Surfaceable, Enabling { @objc(VDSButtonBase) open class ButtonBase: UIButton, Buttonable, ViewProtocol, UserInfoable, Clickable { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + initialSetup() + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- @@ -99,27 +117,9 @@ open class ButtonBase: UIButton, Buttonable, ViewProtocol, UserInfoable, Clickab /// Whether the Control is enabled or not. open override var isEnabled: Bool { didSet { setNeedsUpdate() } } - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - initialSetup() - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - initialSetup() - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - initialSetup() - } //-------------------------------------------------- - // MARK: - Public Methods + // MARK: - Lifecycle //-------------------------------------------------- open func initialSetup() { if !initialSetupPerformed { @@ -131,12 +131,24 @@ open class ButtonBase: UIButton, Buttonable, ViewProtocol, UserInfoable, Clickab } } + open func setup() { translatesAutoresizingMaskIntoConstraints = false titleLabel?.adjustsFontSizeToFitWidth = false titleLabel?.lineBreakMode = .byTruncatingTail - + } + + open func updateView() { + updateLabel() + } + + open func updateAccessibility() { + if isEnabled { + accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) + } } open func reset() { @@ -159,21 +171,8 @@ open class ButtonBase: UIButton, Buttonable, ViewProtocol, UserInfoable, Clickab return CGSize(width: adjustedWidth, height: adjustedHeight) } - /// Used to make changes to the View based off a change events or from local properties. - open func updateView() { - updateLabel() - } - - open func updateAccessibility() { - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } - } - //-------------------------------------------------- - // MARK: - PRIVATE + // MARK: - Private Methods //-------------------------------------------------- private func updateLabel() { diff --git a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift index a45fb847..92c501d6 100644 --- a/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift +++ b/VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift @@ -15,6 +15,21 @@ import Combine @objc(VDSButtonGroup) open class ButtonGroup: View { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- @@ -69,6 +84,23 @@ open class ButtonGroup: View { } } + /// Whether this object is enabled or not + override open var isEnabled: Bool { + didSet { + buttons.forEach { $0.isEnabled = isEnabled } + } + } + + /// Current Surface and this is used to pass down to child objects that implement Surfacable + override open var surface: Surface { + didSet { + buttons.forEach { button in + var b = button + b.surface = surface + } + } + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -91,40 +123,6 @@ open class ButtonGroup: View { } }() - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- - /// Whether this object is enabled or not - override open var isEnabled: Bool { - didSet { - buttons.forEach { $0.isEnabled = isEnabled } - } - } - - /// Current Surface and this is used to pass down to child objects that implement Surfacable - override open var surface: Surface { - didSet { - buttons.forEach { button in - var b = button - b.surface = surface - } - } - } - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } //-------------------------------------------------- // MARK: - Public Methods //-------------------------------------------------- @@ -169,9 +167,6 @@ open class ButtonGroup: View { } extension ButtonGroup: UICollectionViewDataSource, UICollectionViewDelegate { - //-------------------------------------------------- - // MARK: - UICollectionViewDataSource - //-------------------------------------------------- public func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } diff --git a/VDS/Components/Buttons/TextLink/TextLink.swift b/VDS/Components/Buttons/TextLink/TextLink.swift index 40424978..0112db87 100644 --- a/VDS/Components/Buttons/TextLink/TextLink.swift +++ b/VDS/Components/Buttons/TextLink/TextLink.swift @@ -19,6 +19,20 @@ import Combine /// to its parent this object will stretch to the parent's width. @objc(VDSTextLink) open class TextLink: ButtonBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } //-------------------------------------------------- // MARK: - Private Properties @@ -30,7 +44,7 @@ open class TextLink: ButtonBase { } //-------------------------------------------------- - // MARK: - Properties + // MARK: - Public Properties //-------------------------------------------------- open var size: ButtonSize = .large { didSet { setNeedsUpdate() }} @@ -62,22 +76,7 @@ open class TextLink: ButtonBase { } //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - //-------------------------------------------------- - // MARK: - Public Methods + // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { @@ -96,6 +95,16 @@ open class TextLink: ButtonBase { } } + /// Used to make changes to the View based off a change events or from local properties. + open override func updateView() { + //need to set the properties so the super class + //can render out the label correctly + line.backgroundColor = textColor + + //always call last so the label is rendered + super.updateView() + } + /// Resets to default settings. open override func reset() { super.reset() @@ -109,21 +118,9 @@ open class TextLink: ButtonBase { setNeedsUpdate() } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- /// The natural size for the receiving view, considering only properties of the view itself. open override var intrinsicContentSize: CGSize { return titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize } - /// Used to make changes to the View based off a change events or from local properties. - open override func updateView() { - //need to set the properties so the super class - //can render out the label correctly - line.backgroundColor = textColor - - //always call last so the label is rendered - super.updateView() - } } diff --git a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift index 8c20672f..3e6c607f 100644 --- a/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift +++ b/VDS/Components/Buttons/TextLinkCaret/TextLinkCaret.swift @@ -19,6 +19,20 @@ import Combine /// to its parent this object will stretch to the parent's width. @objc(VDSTextLinkCaret) open class TextLinkCaret: ButtonBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } //-------------------------------------------------- // MARK: - Enums @@ -63,24 +77,9 @@ open class TextLinkCaret: ButtonBase { $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) $0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted) } - + //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - //-------------------------------------------------- - // MARK: - Public Methods + // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { @@ -88,6 +87,12 @@ open class TextLinkCaret: ButtonBase { accessibilityTraits = .link } + /// Used to make changes to the View based off a change events or from local properties. + open override func updateView() { + imageAttribute = CaretLabelAttribute(tintColor: textColor, position: iconPosition) + super.updateView() + } + /// Resets to default settings. open override func reset() { super.reset() @@ -95,21 +100,11 @@ open class TextLinkCaret: ButtonBase { text = nil } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- /// The natural size for the receiving view, considering only properties of the view itself. override open var intrinsicContentSize: CGSize { //get the labels size, if not the button return titleLabel?.intrinsicContentSize ?? super.intrinsicContentSize } - - /// Used to make changes to the View based off a change events or from local properties. - open override func updateView() { - imageAttribute = CaretLabelAttribute(tintColor: textColor, position: iconPosition) - super.updateView() - } - } extension TextLinkCaret { diff --git a/VDS/Components/Checkbox/Checkbox.swift b/VDS/Components/Checkbox/Checkbox.swift index 95a81016..564979f3 100644 --- a/VDS/Components/Checkbox/Checkbox.swift +++ b/VDS/Components/Checkbox/Checkbox.swift @@ -11,11 +11,35 @@ import Combine import VDSColorTokens import VDSFormControlsTokens +/// Checkboxes are a multi-select component through which a customer indicates a choice. This is also used within +/// ``CheckboxItem`` and ``CheckboxGroup`` @objc(VDSCheckbox) open class Checkbox: SelectorBase { - + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + /// Whether or not there is animation when the checkbox changes state from non-selected to a selected state. open var isAnimated: Bool = false { didSet { setNeedsUpdate() }} - + + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() @@ -39,6 +63,7 @@ open class Checkbox: SelectorBase { selectorColorConfiguration.setSurfaceColors(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight, forState: .selected) } + /// This will checkbox the state of the Selector and execute the actionBlock if provided. open override func toggle() { //removed error if showError && isSelected == false { diff --git a/VDS/Components/Checkbox/CheckboxGroup.swift b/VDS/Components/Checkbox/CheckboxGroup.swift index dade0aa3..221f4463 100644 --- a/VDS/Components/Checkbox/CheckboxGroup.swift +++ b/VDS/Components/Checkbox/CheckboxGroup.swift @@ -8,18 +8,37 @@ import Foundation import UIKit +/// When the choice has multiple options, use a checkbox group. For example, use a checkbox group when +/// asking a customer which attributes they would like to filter their search by. This uses ``CheckboxItem`` +/// to allow user selection. @objc(VDSCheckboxGroup) open class CheckboxGroup: SelectorGroupHandlerBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + /// Arrary of ``CheckboxItem`` within this group that are selected. open var selectedHandlers: [CheckboxItem]? { let selected = selectorViews.filter{ $0.isSelected == true } guard selected.count > 0 else { return nil } return selected } + /// Arrary of ``CheckboxItem`` within this group. open override var selectorViews: [CheckboxItem] { willSet { mainStackView.arrangedSubviews.forEach { $0.removeFromSuperview() } @@ -35,7 +54,8 @@ open class CheckboxGroup: SelectorGroupHandlerBase { } } - open var selectorModels: [CheckboxModel]? { + /// Arrary of ``CheckboxItemModel`` within this group that are selected. + open var selectorModels: [CheckboxItemModel]? { didSet { if let selectorModels { selectorViews = selectorModels.enumerated().map { index, model in @@ -111,7 +131,7 @@ open class CheckboxGroup: SelectorGroupHandlerBase { } extension CheckboxGroup { - public struct CheckboxModel : Surfaceable, Initable, FormFieldable, Errorable { + public struct CheckboxItemModel : Surfaceable, Initable, FormFieldable, Errorable { /// Whether this object is disabled or not public var disabled: Bool diff --git a/VDS/Components/Checkbox/CheckboxItem.swift b/VDS/Components/Checkbox/CheckboxItem.swift index c8e6380e..6dd4c2ad 100644 --- a/VDS/Components/Checkbox/CheckboxItem.swift +++ b/VDS/Components/Checkbox/CheckboxItem.swift @@ -11,11 +11,7 @@ import UIKit /// Checkboxes are a multi-select component through which a customer indicates a choice. If a binary choice, the component is a checkbox. If the choice has multiple options, the component is a ``CheckboxGroup``. @objc(VDSCheckboxItem) open class CheckboxItem: SelectorItemBase { - //-------------------------------------------------- - // MARK: - Properties - //-------------------------------------------------- - open var isAnimated: Bool = false { didSet { setNeedsUpdate() }} - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -31,6 +27,11 @@ open class CheckboxItem: SelectorItemBase { super.init(coder: coder) } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + open var isAnimated: Bool = false { didSet { setNeedsUpdate() }} + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 70329b5d..115bdcaf 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -11,20 +11,36 @@ import VDSColorTokens @objc(VDSButtonIcon) open class ButtonIcon: Control { + //-------------------------------------------------- - // MARK: - Models + // MARK: - Initializers //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- + /// Enum for the type of button based on the contrast. public enum Kind: String, CaseIterable { case ghost, lowContrast, highContrast } + /// Enum for the background inside icon button determining the surface type. public enum SurfaceType: String, CaseIterable { case colorFill, media } + /// Enum for the size of button icon and icon public enum Size: String, EnumSubset { case large case small @@ -59,17 +75,37 @@ open class ButtonIcon: Control { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + /// Icon object used to render out the Icon for this ButtonIcon. open var icon = Icon() + /// Determines the type of button based on the contrast. open var kind: Kind = .ghost { didSet { setNeedsUpdate() } } + + /// Applies background inside icon button determining the surface type. open var surfaceType: SurfaceType = .colorFill { didSet { setNeedsUpdate() } } + + /// Icon Name used within the Icon. open var iconName: Icon.Name? { didSet { setNeedsUpdate() } } + + /// Icon Name used within the Icon within the Selected State. open var selectedIconName: Icon.Name? { didSet { setNeedsUpdate() } } + + /// Sets the size of button icon and icon. open var size: Size = .large { didSet { setNeedsUpdate() } } + + /// Sets the size of button icon and icon. open var customSize: Int? { didSet { setNeedsUpdate() }} + + /// If provided, the button icon will have a box shadow. open var floating: Bool = false { didSet { setNeedsUpdate() } } + + /// If true, container shrinks to fit the size of the icon for kind equals .ghost. open var fitToIcon: Bool = false { didSet { setNeedsUpdate() } } + + /// If set to true, the button icon will not have a border. open var hideBorder: Bool = true { didSet { setNeedsUpdate() } } + + /// Used to move the icon inside the button in both x and y axis. open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } } //-------------------------------------------------- @@ -205,24 +241,9 @@ open class ButtonIcon: Control { }.eraseToAnyColorable() }() } - + //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - - //-------------------------------------------------- - // MARK: - Lifecycle + // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { @@ -281,10 +302,6 @@ open class ButtonIcon: Control { setNeedsLayout() } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- - open override func layoutSubviews() { super.layoutSubviews() diff --git a/VDS/Components/Icon/Icon.swift b/VDS/Components/Icon/Icon.swift index 9f6e9810..8ffbc89d 100644 --- a/VDS/Components/Icon/Icon.swift +++ b/VDS/Components/Icon/Icon.swift @@ -13,6 +13,21 @@ import Combine @objc(VDSIcon) open class Icon: View { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- @@ -46,7 +61,6 @@ open class Icon: View { //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- - /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() @@ -65,18 +79,6 @@ open class Icon: View { accessibilityTraits = .image } - /// Resets to default settings. - open override func reset() { - super.reset() - color = VDSColor.paletteBlack - imageView.image = nil - } - - /// The natural size for the receiving view, considering only properties of the view itself. - open override var intrinsicContentSize: CGSize { - dimensions - } - /// Used to make changes to the View based off a change events or from local properties. open override func updateView() { super.updateView() @@ -100,7 +102,22 @@ open class Icon: View { invalidateIntrinsicContentSize() } + + /// Resets to default settings. + open override func reset() { + super.reset() + color = VDSColor.paletteBlack + imageView.image = nil + } + + /// The natural size for the receiving view, considering only properties of the view itself. + open override var intrinsicContentSize: CGSize { + dimensions + } + //-------------------------------------------------- + // MARK: - Private Methods + //-------------------------------------------------- private func getImage(for imageName: String) -> UIImage? { return BundleManager.shared.image(for: imageName) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 0f9ddcd3..0ac4d081 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -13,6 +13,24 @@ import Combine @objc(VDSLabel) open class Label: UILabel, ViewProtocol, UserInfoable { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + initialSetup() + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + initialSetup() + } + //-------------------------------------------------- // MARK: - Combine Properties //-------------------------------------------------- @@ -20,10 +38,64 @@ open class Label: UILabel, ViewProtocol, UserInfoable { open var subscribers = Set() //-------------------------------------------------- - // MARK: - Properties + // MARK: - Private Properties //-------------------------------------------------- private var initialSetupPerformed = false + private var tapGesture: UITapGestureRecognizer? { + willSet { + if let tapGesture = tapGesture, newValue == nil { + removeGestureRecognizer(tapGesture) + } else if let gesture = newValue, tapGesture == nil { + addGestureRecognizer(gesture) + } + } + } + + private var actions: [LabelAction] = [] { + didSet { + if actions.isEmpty { + tapGesture = nil + isUserInteractionEnabled = true + accessibilityTraits = .staticText + } else { + //add tap gesture + if tapGesture == nil { + let singleTap = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped)) + singleTap.numberOfTapsRequired = 1 + tapGesture = singleTap + } + if actions.count > 1 { + actions.sort { first, second in + return first.range.location < second.range.location + } + } + } + } + } + + //-------------------------------------------------- + // MARK: - Private Models + //-------------------------------------------------- + private struct LabelAction { + var range: NSRange + var action: PassthroughSubject + var accessibilityId: Int = 0 + + func performAction() { + action.send() + } + + init(range: NSRange, action: PassthroughSubject, accessibilityID: Int = 0) { + self.range = range + self.action = action + self.accessibilityId = accessibilityID + } + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- /// Key of whether or not updateView() is called in setNeedsUpdate() open var shouldUpdateView: Bool = true @@ -67,27 +139,9 @@ open class Label: UILabel, ViewProtocol, UserInfoable { $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false) }.eraseToAnyColorable(){ didSet { setNeedsUpdate() }} - + //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - initialSetup() - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - initialSetup() - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - initialSetup() - } - - //-------------------------------------------------- - // MARK: - Public Methods + // MARK: - Lifecycle //-------------------------------------------------- open func initialSetup() { if !initialSetupPerformed { @@ -126,16 +180,6 @@ open class Label: UILabel, ViewProtocol, UserInfoable { setNeedsUpdate() } - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- - open override func drawText(in rect: CGRect) { - super.drawText(in: rect.inset(by: edgeInsets)) - } - - //-------------------------------------------------- - // MARK: - Overrides - //-------------------------------------------------- /// Used to make changes to the View based off a change events or from local properties. open func updateView() { if !useAttributedText { @@ -168,7 +212,37 @@ open class Label: UILabel, ViewProtocol, UserInfoable { accessibilityLabel = text } - // MARK: - Private Attributes + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- + open override func drawText(in rect: CGRect) { + super.drawText(in: rect.inset(by: edgeInsets)) + } + + open override func layoutSubviews() { + super.layoutSubviews() + applyActions() + } + + open override func accessibilityActivate() -> Bool { + + guard let accessibleActions = accessibilityCustomActions else { return false } + + for actionable in actions { + for action in accessibleActions { + if action.hash == actionable.accessibilityId { + actionable.performAction() + return true + } + } + } + + return false + } + + //-------------------------------------------------- + // MARK: - Private Methods + //-------------------------------------------------- private func applyAttributes(_ mutableAttributedString: NSMutableAttributedString) { actions = [] @@ -181,11 +255,6 @@ open class Label: UILabel, ViewProtocol, UserInfoable { } } } - - open override func layoutSubviews() { - super.layoutSubviews() - applyActions() - } private func applyActions() { actions = [] @@ -219,57 +288,6 @@ open class Label: UILabel, ViewProtocol, UserInfoable { } } } - - //-------------------------------------------------- - // MARK: - Actionable - //-------------------------------------------------- - private var tapGesture: UITapGestureRecognizer? { - willSet { - if let tapGesture = tapGesture, newValue == nil { - removeGestureRecognizer(tapGesture) - } else if let gesture = newValue, tapGesture == nil { - addGestureRecognizer(gesture) - } - } - } - - private struct LabelAction { - var range: NSRange - var action: PassthroughSubject - var accessibilityId: Int = 0 - - func performAction() { - action.send() - } - - init(range: NSRange, action: PassthroughSubject, accessibilityID: Int = 0) { - self.range = range - self.action = action - self.accessibilityId = accessibilityID - } - } - - private var actions: [LabelAction] = [] { - didSet { - if actions.isEmpty { - tapGesture = nil - isUserInteractionEnabled = true - accessibilityTraits = .staticText - } else { - //add tap gesture - if tapGesture == nil { - let singleTap = UITapGestureRecognizer(target: self, action: #selector(textLinkTapped)) - singleTap.numberOfTapsRequired = 1 - tapGesture = singleTap - } - if actions.count > 1 { - actions.sort { first, second in - return first.range.location < second.range.location - } - } - } - } - } @objc private func textLinkTapped(_ gesture: UITapGestureRecognizer) { for actionable in actions { @@ -280,10 +298,7 @@ open class Label: UILabel, ViewProtocol, UserInfoable { } } } - - //-------------------------------------------------- - // MARK: - Accessibility For Actions - //-------------------------------------------------- + private func customAccessibilityAction(text: String?, range: NSRange, accessibleText: String? = nil) -> UIAccessibilityCustomAction? { guard let text = text, let attributedText else { return nil } @@ -309,6 +324,7 @@ open class Label: UILabel, ViewProtocol, UserInfoable { element.accessibilityLabel = actionText element.accessibilityTraits = .link element.accessibilityFrameInContainerSpace = substringBounds + //TODO: accessibilityHint for Label // element.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "swipe_to_select_with_action_hint") @@ -320,9 +336,7 @@ open class Label: UILabel, ViewProtocol, UserInfoable { return accessibleAction } - - - @objc public func accessibilityCustomAction(_ action: UIAccessibilityCustomAction) { + @objc private func accessibilityCustomAction(_ action: UIAccessibilityCustomAction) { for actionable in actions { if action.hash == actionable.accessibilityId { @@ -331,20 +345,4 @@ open class Label: UILabel, ViewProtocol, UserInfoable { } } } - - open override func accessibilityActivate() -> Bool { - - guard let accessibleActions = accessibilityCustomActions else { return false } - - for actionable in actions { - for action in accessibleActions { - if action.hash == actionable.accessibilityId { - actionable.performAction() - return true - } - } - } - - return false - } } diff --git a/VDS/Components/Line/Line.swift b/VDS/Components/Line/Line.swift index 990bc1e2..b78a30a6 100644 --- a/VDS/Components/Line/Line.swift +++ b/VDS/Components/Line/Line.swift @@ -12,6 +12,21 @@ import VDSColorTokens @objc(VDSLine) open class Line: View { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- diff --git a/VDS/Components/Loader/Loader.swift b/VDS/Components/Loader/Loader.swift index 2301b5aa..8bb3b6ae 100644 --- a/VDS/Components/Loader/Loader.swift +++ b/VDS/Components/Loader/Loader.swift @@ -13,6 +13,22 @@ import VDSColorTokens @objc(VDSLoader) /// A loader is an indicator that uses animation to show customers that there is an indefinite amount of wait time while a task is ongoing, e.g. a page is loading, a form is being submitted. The component disappears when the task is complete. open class Loader: View { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index da942ebe..5f63dc0a 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -14,6 +14,21 @@ import Combine /// A VDS Component that will render a view with information open class Notification: View { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- @@ -186,22 +201,7 @@ open class Notification: View { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: true) } - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- diff --git a/VDS/Components/RadioBox/RadioBoxGroup.swift b/VDS/Components/RadioBox/RadioBoxGroup.swift index 1bbf9a6c..7b31ed47 100644 --- a/VDS/Components/RadioBox/RadioBoxGroup.swift +++ b/VDS/Components/RadioBox/RadioBoxGroup.swift @@ -11,6 +11,21 @@ import UIKit @objc(VDSRadioBoxGroup) open class RadioBoxGroup: SelectorGroupSelectedHandlerBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -30,7 +45,7 @@ open class RadioBoxGroup: SelectorGroupSelectedHandlerBase { } } - open var selectorModels: [RadioBoxModel]? { + open var selectorModels: [RadioBoxItemModel]? { didSet { if let selectorModels { selectorViews = selectorModels.enumerated().map { index, model in @@ -107,7 +122,7 @@ open class RadioBoxGroup: SelectorGroupSelectedHandlerBase { } extension RadioBoxGroup { - public struct RadioBoxModel: Surfaceable, Initable, FormFieldable { + public struct RadioBoxItemModel: Surfaceable, Initable, FormFieldable { /// Whether this object is disabled or not public var disabled: Bool /// Current Surface and this is used to pass down to child objects that implement Surfacable diff --git a/VDS/Components/RadioButton/RadioButton.swift b/VDS/Components/RadioButton/RadioButton.swift index e55d191f..416f89db 100644 --- a/VDS/Components/RadioButton/RadioButton.swift +++ b/VDS/Components/RadioButton/RadioButton.swift @@ -14,8 +14,29 @@ import VDSFormControlsTokens @objc(VDSRadioButton) open class RadioButton: SelectorBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- open var selectedSize = CGSize(width: 10, height: 10) { didSet { setNeedsUpdate() }} + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() diff --git a/VDS/Components/RadioButton/RadioButtonGroup.swift b/VDS/Components/RadioButton/RadioButtonGroup.swift index f3898d86..33a1202c 100644 --- a/VDS/Components/RadioButton/RadioButtonGroup.swift +++ b/VDS/Components/RadioButton/RadioButtonGroup.swift @@ -11,6 +11,21 @@ import UIKit @objc(VDSRadioButtonGroup) open class RadioButtonGroup: SelectorGroupSelectedHandlerBase { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -30,7 +45,7 @@ open class RadioButtonGroup: SelectorGroupSelectedHandlerBase { } } - open var selectorModels: [RadioButtonModel]? { + open var selectorModels: [RadioButtonItemModel]? { didSet { if let selectorModels { selectorViews = selectorModels.enumerated().map { index, model in @@ -115,7 +130,7 @@ open class RadioButtonGroup: SelectorGroupSelectedHandlerBase { } extension RadioButtonGroup { - public struct RadioButtonModel: Surfaceable, Initable, FormFieldable, Errorable { + public struct RadioButtonItemModel: Surfaceable, Initable, FormFieldable, Errorable { /// Whether this object is disabled or not public var disabled: Bool diff --git a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift index a420022f..4cf0e729 100644 --- a/VDS/Components/RadioSwatch/RadioSwatchGroup.swift +++ b/VDS/Components/RadioSwatch/RadioSwatchGroup.swift @@ -12,6 +12,21 @@ import Combine @objc(VDSRadioSwatchGroup) open class RadioSwatchGroup: SelectorGroupSelectedHandlerBase, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index 1935e25c..d0234319 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -13,6 +13,22 @@ extension Tabs { @objc(VDSTab) open class Tab: Control { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -103,21 +119,6 @@ extension Tabs { labelWidthConstraint?.isActive = true } - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - required public convenience init() { - self.init(frame: .zero) - } - //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index 239075a7..3c5c7814 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -13,6 +13,21 @@ import VDSColorTokens @objc(VDSTabs) open class Tabs: View { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- @@ -148,21 +163,6 @@ open class Tabs: View { orientation == .horizontal && overflow == .scroll && !fillContainer } - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - public override init(frame: CGRect) { - super.init(frame: frame) - } - - public convenience required init() { - self.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- diff --git a/VDS/Components/Tabs/TabsContainer.swift b/VDS/Components/Tabs/TabsContainer.swift index 91087770..205dc2cc 100644 --- a/VDS/Components/Tabs/TabsContainer.swift +++ b/VDS/Components/Tabs/TabsContainer.swift @@ -10,6 +10,22 @@ import UIKit @objc(VDSTabsContainer) open class TabsContainer: View { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index 5cf71554..496a917b 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -13,13 +13,7 @@ import Combine @objc(VDSEntryField) open class EntryField: Control, Changeable { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- - public enum HelperTextPlacement: String, CaseIterable { - case bottom, right - } - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -34,7 +28,14 @@ open class EntryField: Control, Changeable { public required init?(coder: NSCoder) { super.init(coder: coder) } - + + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum HelperTextPlacement: String, CaseIterable { + case bottom, right + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index 17c86131..9ce5b37c 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -13,13 +13,7 @@ import Combine @objc(VDSInputField) open class InputField: EntryField, UITextFieldDelegate { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- - public enum FieldType: String, CaseIterable { - case text, number, calendar, inlineAction, password, creditCard, tel, date, securityCode - } - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -34,7 +28,14 @@ open class InputField: EntryField, UITextFieldDelegate { public required init?(coder: NSCoder) { super.init(coder: coder) } - + + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum FieldType: String, CaseIterable { + case text, number, calendar, inlineAction, password, creditCard, tel, date, securityCode + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 97425a5a..4f068809 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -14,14 +14,6 @@ import Combine @objc(VDSTilelet) open class Tilelet: TileContainer { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- - public enum TextPosition: String, CaseIterable { - case top - case bottom - } - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -36,6 +28,14 @@ open class Tilelet: TileContainer { public required init?(coder: NSCoder) { super.init(coder: coder) } + + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum TextPosition: String, CaseIterable { + case top + case bottom + } //-------------------------------------------------- // MARK: - Private Properties diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 5f34c050..62ce38fc 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -13,15 +13,6 @@ import Combine @objc(VDSTitleLockup) open class TitleLockup: View { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- - public enum TextPosition: String, EnumSubset { - case left, center - - public var defaultValue: VDS.TextPosition { .left } - } - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -36,6 +27,15 @@ open class TitleLockup: View { public required init?(coder: NSCoder) { super.init(coder: coder) } + + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum TextPosition: String, EnumSubset { + case left, center + + public var defaultValue: VDS.TextPosition { .left } + } //-------------------------------------------------- // MARK: - Private Properties diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 6e93a75d..06d49407 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -12,21 +12,7 @@ import Combine @objc(VDSToggle) open class Toggle: Control, Changeable { - //-------------------------------------------------- - // MARK: - Enums - //-------------------------------------------------- - public enum TextSize: String, CaseIterable { - case small, large - } - - public enum TextWeight: String, CaseIterable { - case regular, bold - } - - public enum TextPosition: String, CaseIterable { - case left, right - } - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -41,6 +27,21 @@ open class Toggle: Control, Changeable { public required init?(coder: NSCoder) { super.init(coder: coder) } + + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum TextSize: String, CaseIterable { + case small, large + } + + public enum TextWeight: String, CaseIterable { + case regular, bold + } + + public enum TextPosition: String, CaseIterable { + case left, right + } //-------------------------------------------------- // MARK: - Constraints diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index c5db18c5..9673df4e 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -14,6 +14,21 @@ import Combine @objc(VDSTooltip) open class Tooltip: Control, TooltipLaunchable { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Enums //-------------------------------------------------- @@ -88,22 +103,7 @@ open class Tooltip: Control, TooltipLaunchable { $0.setSurfaceColors(VDSColor.elementsBrandhighlight, VDSColor.elementsBrandhighlight, forState: .highlighted) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) } - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - required public init() { - super.init(frame: .zero) - } - - public override init(frame: CGRect) { - super.init(frame: .zero) - } - - public required init?(coder: NSCoder) { - super.init(coder: coder) - } - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- diff --git a/VDS/Components/Tooltip/TooltipDialog.swift b/VDS/Components/Tooltip/TooltipDialog.swift index 9341f127..f63739b7 100644 --- a/VDS/Components/Tooltip/TooltipDialog.swift +++ b/VDS/Components/Tooltip/TooltipDialog.swift @@ -10,6 +10,22 @@ import UIKit import VDSColorTokens open class TooltipDialog: View, UIScrollViewDelegate { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- diff --git a/VDS/Components/Tooltip/TrailingTooltipLabel.swift b/VDS/Components/Tooltip/TrailingTooltipLabel.swift index 2171b374..b5c39848 100644 --- a/VDS/Components/Tooltip/TrailingTooltipLabel.swift +++ b/VDS/Components/Tooltip/TrailingTooltipLabel.swift @@ -12,6 +12,21 @@ import Combine @objc(VDSTrailingTooltipLabel) open class TrailingTooltipLabel: View, TooltipLaunchable { + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + required public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: .zero) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + //-------------------------------------------------- // MARK: - Private Properties //--------------------------------------------------