// // DropShadowable.swift // VDS // // Created by Bandaru, Krishna Kishore on 16/02/24. // import Foundation import UIKit /** DropShadowable protocol helps with the configuration values for adding drop shadows for light & dark surfaces. */ protocol DropShadowable { ///Shadow Color configuration for light and dark surfaces var shadowColorConfiguration: AnyColorable { get set } ///Shadow Opacity configuration for light and dark surfaces var shadowOpacityConfiguration: SurfaceConfigurationValue { get set } ///Shadow Offset configuration for light and dark surfaces var shadowOffsetConfiguration: SurfaceConfigurationValue { get set } ///Shadow Radius configuration for light and dark surfaces var shadowRadiusConfiguration: SurfaceConfigurationValue { get set } } /** DropShadowableConfiguration protocol helps with multiple drop shadows configurations can be added to a view. */ protocol DropShadowableConfiguration { ///Configurations are the DropShadowable list, these are applied on the view var configurations: [DropShadowable] { get } } /** Extension on ViewProtocol for adding drop shadows & gradient layer on view. */ extension ViewProtocol where Self: UIView { func addDropShadow(_ config: DropShadowable) { addDropShadows([config]) } func addDropShadows(_ configs: [DropShadowable]) { removeDropShadows() layer.backgroundColor = backgroundColor?.cgColor layer.masksToBounds = false for config in configs { let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius) let shadowLayer = CALayer() shadowLayer.shadowPath = shadowPath.cgPath shadowLayer.frame = bounds shadowLayer.position = .init(x: bounds.midX, y: bounds.midY) shadowLayer.backgroundColor = backgroundColor?.cgColor shadowLayer.cornerRadius = layer.cornerRadius shadowLayer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor shadowLayer.shadowOpacity = Float(config.shadowOpacityConfiguration.value(for: self)) shadowLayer.shadowOffset = config.shadowOffsetConfiguration.value(for: self) shadowLayer.shadowRadius = config.shadowRadiusConfiguration.value(for: self) shadowLayer.name = "dropShadowLayer" shadowLayer.shouldRasterize = true shadowLayer.rasterizationScale = UIScreen.main.scale layer.insertSublayer(shadowLayer, at: 0) } } func removeDropShadows() { layer.sublayers?.removeAll { $0.name == "dropShadowLayer" } } func addGradientLayer(with firstColor: UIColor, secondColor: UIColor) { removeGradientLayer() let gradientLayer = CAGradientLayer() gradientLayer.frame = bounds gradientLayer.startPoint = CGPoint(x: 0, y: 1) gradientLayer.endPoint = CGPoint(x: 1, y: 0) gradientLayer.position = center gradientLayer.shouldRasterize = true gradientLayer.backgroundColor = UIColor.clear.cgColor gradientLayer.rasterizationScale = UIScreen.main.scale gradientLayer.cornerRadius = layer.cornerRadius gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor] gradientLayer.name = "gradientLayer" layer.insertSublayer(gradientLayer, at: 0) } func removeGradientLayer() { layer.sublayers?.removeAll { $0.name == "gradientLayer" } } }