created basebutton

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-11-22 13:07:27 -06:00
parent dd6fddbcf4
commit cb2d8145a2
2 changed files with 186 additions and 0 deletions

View File

@ -61,6 +61,7 @@
EAB5FED429267EB300998C17 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FED329267EB300998C17 /* UIView.swift */; };
EAB5FEED2927E1B200998C17 /* ButtonGroupPositionLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEEC2927E1B200998C17 /* ButtonGroupPositionLayout.swift */; };
EAB5FEF12927F4AA00998C17 /* SelfSizingCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEF02927F4AA00998C17 /* SelfSizingCollectionView.swift */; };
EAB5FEF5292D371F00998C17 /* BaseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB5FEF4292D371F00998C17 /* BaseButton.swift */; };
EAC9257D29119B5400091998 /* TextLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9257C29119B5400091998 /* TextLink.swift */; };
EAC925832911B35400091998 /* TextLinkCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC925822911B35300091998 /* TextLinkCaret.swift */; };
EAC925842911C63100091998 /* Colorable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA5EEDF28F49DB3003B3210 /* Colorable.swift */; };
@ -153,6 +154,7 @@
EAB5FED329267EB300998C17 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
EAB5FEEC2927E1B200998C17 /* ButtonGroupPositionLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupPositionLayout.swift; sourceTree = "<group>"; };
EAB5FEF02927F4AA00998C17 /* SelfSizingCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelfSizingCollectionView.swift; sourceTree = "<group>"; };
EAB5FEF4292D371F00998C17 /* BaseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseButton.swift; sourceTree = "<group>"; };
EAC9257C29119B5400091998 /* TextLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLink.swift; sourceTree = "<group>"; };
EAC925822911B35300091998 /* TextLinkCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkCaret.swift; sourceTree = "<group>"; };
EAC925872911C9DE00091998 /* TextEntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = "<group>"; };
@ -203,6 +205,7 @@
isa = PBXGroup;
children = (
5FC35BE228D51405004EBEAC /* Button.swift */,
EAB5FEF4292D371F00998C17 /* BaseButton.swift */,
);
path = Button;
sourceTree = "<group>";
@ -654,6 +657,7 @@
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */,
EAC925842911C63100091998 /* Colorable.swift in Sources */,
EA3361C5289030FC0071C351 /* Accessable.swift in Sources */,
EAB5FEF5292D371F00998C17 /* BaseButton.swift in Sources */,
EA978EC5291D6AFE00ACC883 /* AnyLabelAttribute.swift in Sources */,
EA33622C2891E73B0071C351 /* FontProtocol.swift in Sources */,
EAF7F11728A1475A00B287F5 /* RadioButton.swift in Sources */,

View File

@ -0,0 +1,182 @@
//
// BaseButton.swift
// VDS
//
// Created by Matt Bruce on 11/22/22.
//
import Foundation
import UIKit
import VDSColorTokens
import VDSFormControlsTokens
import Combine
public protocol Buttonable: UIControl, Surfaceable, Disabling {
var availableSizes: [ButtonSize] { get }
var text: String? { get set }
var intrinsicContentSize: CGSize { get }
}
@objc(VDSBaseButton)
open class BaseButton: UIButton, Buttonable, Handlerable, ViewProtocol, Resettable {
//--------------------------------------------------
// MARK: - Combine Properties
//--------------------------------------------------
public var subject = PassthroughSubject<Void, Never>()
public var subscribers = Set<AnyCancellable>()
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private var initialSetupPerformed = false
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
open var availableSizes: [ButtonSize] { [] }
open var text: String? { didSet { didChange() } }
open var attributes: [any LabelAttributeModel]? { nil }
open var surface: Surface = .light { didSet { didChange() }}
open var disabled: Bool = false { didSet { isEnabled = !disabled } }
open override var isHighlighted: Bool { didSet { if isHighlighted != oldValue { updateView() } } }
open var typograpicalStyle: TypographicalStyle { .defaultStyle }
open var textColor: UIColor { .black }
open override var isEnabled: Bool {
get { !disabled }
set {
if disabled != !newValue {
disabled = !newValue
}
isUserInteractionEnabled = isEnabled
didChange()
}
}
//--------------------------------------------------
// 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 Functions
//--------------------------------------------------
open func initialSetup() {
if !initialSetupPerformed {
backgroundColor = .clear
translatesAutoresizingMaskIntoConstraints = false
accessibilityCustomActions = []
accessibilityTraits = .staticText
setup()
setupDidChangeEvent()
updateView()
}
}
open func setup() {
translatesAutoresizingMaskIntoConstraints = false
titleLabel?.adjustsFontSizeToFitWidth = false
titleLabel?.lineBreakMode = .byTruncatingTail
}
open func reset() {
surface = .light
disabled = false
text = nil
accessibilityCustomActions = []
accessibilityTraits = .button
}
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
override open var intrinsicContentSize: CGSize {
let intrinsicContentSize = super.intrinsicContentSize
let adjustedWidth = intrinsicContentSize.width + titleEdgeInsets.left + titleEdgeInsets.right
let adjustedHeight = intrinsicContentSize.height + titleEdgeInsets.top + titleEdgeInsets.bottom
return CGSize(width: adjustedWidth, height: adjustedHeight)
}
open func updateView() {
updateLabel()
}
//--------------------------------------------------
// MARK: - PRIVATE
//--------------------------------------------------
private func updateLabel() {
let font = typograpicalStyle.font
//clear the arrays holding actions
accessibilityCustomActions = []
//create the primary string
let startingAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: textColor]
let mutableText = NSMutableAttributedString(string: text ?? "No Text", attributes: startingAttributes)
//set the local lineHeight/lineSpacing attributes
//get the range
let entireRange = NSRange(location: 0, length: mutableText.length)
//set letterSpacing
if typograpicalStyle.letterSpacing > 0.0 {
mutableText.addAttribute(.kern, value: typograpicalStyle.letterSpacing, range: entireRange)
}
let paragraph = NSMutableParagraphStyle().with {
$0.alignment = titleLabel?.textAlignment ?? .center
$0.lineBreakMode = titleLabel?.lineBreakMode ?? .byTruncatingTail
}
//set lineHeight
if typograpicalStyle.lineHeight > 0.0 {
let lineHeight = typograpicalStyle.lineHeight
let adjustment = lineHeight > font.lineHeight ? 2.0 : 1.0
let baselineOffset = (lineHeight - font.lineHeight) / 2.0 / adjustment
paragraph.maximumLineHeight = lineHeight
paragraph.minimumLineHeight = lineHeight
mutableText.addAttribute(.baselineOffset, value: baselineOffset, range: entireRange)
mutableText.addAttribute( .paragraphStyle, value: paragraph, range: entireRange)
} else {
mutableText.addAttribute( .paragraphStyle, value: paragraph, range: entireRange)
}
if let attributes = attributes {
//loop through the models attributes
for attribute in attributes {
//add attribute on the string
attribute.setAttribute(on: mutableText)
}
}
//set the attributed text
setAttributedTitle(mutableText, for: .normal)
setAttributedTitle(mutableText, for: .highlighted)
}
}