vds_ios/VDS/Components/Icon/Icon.swift
Matt Bruce 5d19edbc6e Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/vds_ios.git into refactor/VDSTokens
# Conflicts:
#	VDS.xcodeproj/project.pbxproj
#	VDS/Components/Buttons/ButtonGroup/ButtonGroup.swift
#	VDS/Components/Notification/Notification.swift
#	VDS/Components/TextFields/EntryFieldBase.swift
#	VDS/Components/TileContainer/TileContainer.swift
#	VDS/Extensions/VDSLayout.swift

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-04-02 12:09:30 -05:00

146 lines
4.8 KiB
Swift

//
// Icon.swift
// VDS
//
// Created by Matt Bruce on 1/9/23.
//
import Foundation
import UIKit
import VDSTokens
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.isAccessibilityElement = false
$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 = UIImage.image(for: name, color: imageColor) {
imageView.image = image
} else {
imageView.image = nil
}
invalidateIntrinsicContentSize()
}
/// Resets to default settings.
open override func reset() {
super.reset()
color = VDSColor.paletteBlack
imageView.image = nil
}
open override func updateAccessibility() {
super.updateAccessibility()
accessibilityLabel = name?.rawValue ?? "icon"
}
}
extension UIImage {
/// UIImage helper for finding images based on the Icon.Name which uses the internal BundleManager.
/// - Parameters:
/// - name: Icon.Name rawRepresentable.
/// - color: Color to Tint the image with
/// - renderingMode: UIImage Rendering mode.
/// - Returns: UIImage for this proecess
public static func image(for iconName: Icon.Name, color: UIColor? = nil, renderingMode: UIImage.RenderingMode = .alwaysOriginal) -> UIImage? {
image(representing: iconName, color: color, renderingMode: renderingMode)
}
}