vds_ios/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift
Matt Bruce 636b5ad9c0 refactored naming
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-05-15 11:35:47 -05:00

192 lines
6.5 KiB
Swift

//
// ButtonIcon.swift
// VDS
//
// Created by Matt Bruce on 5/12/23.
//
import Foundation
import UIKit
@objc(VDSButtonIcon)
open class ButtonIcon: Control {
//--------------------------------------------------
// MARK: - Models
//--------------------------------------------------
//--------------------------------------------------
// MARK: - Enums
//--------------------------------------------------
public enum Kind: String, CaseIterable {
case ghost, lowContrast, highContrast
}
public enum SurfaceType: String, CaseIterable {
case colorFill, media
}
public enum Size: String, EnumSubset {
case large
case small
public var defaultValue: Icon.Size { .large }
public var containerSize: CGFloat {
switch self {
case .large:
return 44.0
case .small:
return 32.0
}
}
}
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private var centerXConstraint: NSLayoutConstraint?
private var centerYConstraint: NSLayoutConstraint?
private var layoutGuideWidthConstraint: NSLayoutConstraint?
private var layoutGuideHeightConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
open var icon = Icon()
open var kind: Kind = .ghost { didSet { setNeedsUpdate() } }
open var surfaceType: SurfaceType = .colorFill { didSet { setNeedsUpdate() } }
open var iconName: Icon.Name? { didSet { setNeedsUpdate() } }
open var size: Size = .large { didSet { setNeedsUpdate() } }
open var customSize: Int? { didSet { setNeedsUpdate() }}
open var floating: Bool = false { didSet { setNeedsUpdate() } }
open var hideBorder: Bool = true { didSet { setNeedsUpdate() } }
open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } }
//--------------------------------------------------
// MARK: - Configuration
//--------------------------------------------------
//--------------------------------------------------
// 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
//--------------------------------------------------
open override func setup() {
super.setup()
//create a layoutGuide for the icon to key off of
let iconLayoutGuide = UILayoutGuide()
addLayoutGuide(iconLayoutGuide)
//add the icon
addSubview(icon)
//determines the height/width of the icon
layoutGuideWidthConstraint = iconLayoutGuide.widthAnchor.constraint(equalToConstant: size.containerSize)
layoutGuideHeightConstraint = iconLayoutGuide.heightAnchor.constraint(equalToConstant: size.containerSize)
//determines the center point of the icon
centerXConstraint = icon.centerXAnchor.constraint(equalTo: iconLayoutGuide.centerXAnchor, constant: 0)
centerYConstraint = icon.centerYAnchor.constraint(equalTo: iconLayoutGuide.centerYAnchor, constant: 0)
//activate the constraints
NSLayoutConstraint.activate([layoutGuideWidthConstraint!,
layoutGuideHeightConstraint!,
centerXConstraint!,
centerYConstraint!,
iconLayoutGuide.topAnchor.constraint(equalTo: topAnchor),
iconLayoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
iconLayoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
iconLayoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
}
open override func reset() {
super.reset()
shouldUpdateView = false
kind = .ghost
surfaceType = .colorFill
size = .large
floating = false
hideBorder = true
iconOffset = .init(x: 0, y: 0)
iconName = nil
shouldUpdateView = true
setNeedsUpdate()
}
open override func updateView() {
super.updateView()
//ensure there is an icon to set
if let iconName {
icon.name = iconName
icon.size = size.value
icon.surface = surface
icon.disabled = disabled
icon.customSize = customSize
} else {
icon.reset()
}
// colors
let bgColor = UIColor.red //backgroundColorConfiguration.getColor(self)
let borderColor = UIColor.green// borderColorConfiguration.getColor(self)
backgroundColor = bgColor
layer.borderColor = borderColor.cgColor
icon.layer.borderColor = UIColor.purple.cgColor
setNeedsLayout()
}
open override func layoutSubviews() {
super.layoutSubviews()
let borderWidth = 2.0
let cornerRadius = min(frame.width, frame.height) / 2.0
// calculate center point for child view with offset
let childCenter = CGPoint(x: center.x + iconOffset.x, y: center.y + iconOffset.y)
centerXConstraint?.constant = childCenter.x - center.x
centerYConstraint?.constant = childCenter.y - center.y
// calculate the icon's container size ensuring the padding
var iconLayoutSize = size.containerSize
if let customSize {
iconLayoutSize = CGFloat(customSize)
}
layoutGuideWidthConstraint?.constant = iconLayoutSize
layoutGuideHeightConstraint?.constant = iconLayoutSize
//container
layer.cornerRadius = cornerRadius
layer.borderWidth = borderWidth
//icon
icon.layer.borderWidth = borderWidth
}
}
// MARK: AppleGuidlinesTouchable
extension ButtonIcon: AppleGuidlinesTouchable {
override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
Self.acceptablyOutsideBounds(point: point, bounds: bounds)
}
}