vds_ios/VDS/Components/Icon/Icon.swift
Matt Bruce 924653a726 refactored code
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2023-09-15 14:57:44 -05:00

140 lines
4.5 KiB
Swift

//
// Icon.swift
// VDS
//
// Created by Matt Bruce on 1/9/23.
//
import Foundation
import UIKit
import VDSColorTokens
import Combine
/// An icon is a graphical element that conveys information at a glance. It helps orient
/// a customer, explain functionality and draw attention to interactive elements. Icons
/// should have a functional purpose and should never be used for decoration.
@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
//--------------------------------------------------
private var dimensions: CGSize {
guard let customSize else { return size.dimensions }
return .init(width: customSize, height: customSize)
}
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
/// UIImageView used to render the icon.
open var imageView = UIImageView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.contentMode = .scaleAspectFill
$0.clipsToBounds = true
}
/// Color of the icon.
open var color: UIColor = VDSColor.paletteBlack {
didSet {
if let hex = color.hexString, !UIColor.isVDSColor(color: color) {
print("icon.color is not a VDSColor. Hex: \(hex) is not a supported color")
}
setNeedsUpdate()
}
}
/// Size of the icon.
open var size: Size = .medium { didSet { setNeedsUpdate() } }
/// This will be used to render the icon with corresponding name.
open var name: Name? { didSet { setNeedsUpdate() } }
/// A custom size of the icon.
open var customSize: Int? { didSet { setNeedsUpdate() } }
/// The natural size for the receiving view, considering only properties of the view itself.
open override var intrinsicContentSize: CGSize { dimensions }
//functions
//--------------------------------------------------
// 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()
setContentCompressionResistancePriority(.required, for: .vertical)
setContentHuggingPriority(.required, for: .vertical)
setContentCompressionResistancePriority(.required, for: .horizontal)
setContentHuggingPriority(.required, for: .horizontal)
addSubview(imageView)
imageView.pinToSuperView()
backgroundColor = .clear
isAccessibilityElement = true
accessibilityTraits = .image
}
/// Used to make changes to the View based off a change events or from local properties.
open override func updateView() {
super.updateView()
//get the color for the image
var imageColor = color
//ensure the correct color for white/black colors
if surface == .dark && color == VDSColor.paletteBlack {
imageColor = VDSColor.elementsPrimaryOndark
} else if surface == .light && color == VDSColor.paletteBlack {
imageColor = VDSColor.elementsPrimaryOnlight
}
//get the image name
//set the image
if let name, let image = getImage(for: name.rawValue) {
setImage(image: image, imageColor: imageColor)
} else {
imageView.image = nil
}
invalidateIntrinsicContentSize()
}
/// Resets to default settings.
open override func reset() {
super.reset()
color = VDSColor.paletteBlack
imageView.image = nil
}
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
private func getImage(for imageName: String) -> UIImage? {
return BundleManager.shared.image(for: imageName)
}
private func setImage(image: UIImage, imageColor: UIColor) {
imageView.image = image.withTintColor(imageColor)
}
}