vds_ios/VDS/Protocols/DropShadowable.swift
2024-02-22 22:53:19 +05:30

114 lines
4.4 KiB
Swift

//
// DropShadowable.swift
// VDS
//
// Created by Bandaru, Krishna Kishore on 16/02/24.
//
import Foundation
import UIKit
protocol DropShadowable {
var shadowColorConfiguration: AnyColorable { get set }
var shadowOpacityConfiguration: AnyConfigurationValue<CGFloat> { get set }
var shadowOffsetConfiguration: AnyConfigurationValue<CGSize> { get set }
var shadowRadiusConfiguration: AnyConfigurationValue<CGFloat> { get set }
}
protocol DropShadowableConfiguration {
var configurations: [DropShadowable] { get }
}
final class DropShadowConfiguration: DropShadowable, ObjectWithable {
typealias CGFloatConfigurationValue = AnyConfigurationValue<CGFloat>
typealias CGSizeConfigurationValue = AnyConfigurationValue<CGSize>
var shadowColorConfiguration: AnyColorable
var shadowOpacityConfiguration: CGFloatConfigurationValue
var shadowOffsetConfiguration: CGSizeConfigurationValue
var shadowRadiusConfiguration: CGFloatConfigurationValue
init(shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().eraseToAnyColorable(), shadowOpacity: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0), shadowOffset: CGSizeConfigurationValue = CGSizeConfigurationValue(.zero, .zero), shadowRadius: CGFloatConfigurationValue = CGFloatConfigurationValue(1.0, 1.0)) {
self.shadowColorConfiguration = shadowColorConfiguration
self.shadowOpacityConfiguration = shadowOpacity
self.shadowOffsetConfiguration = shadowOffset
self.shadowRadiusConfiguration = shadowRadius
}
}
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.getValue(self))
shadowLayer.shadowOffset = config.shadowOffsetConfiguration.getValue(self)
shadowLayer.shadowRadius = config.shadowRadiusConfiguration.getValue(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" }
}
}
final class AnyConfigurationValue<ValueType> {
var lightValue: ValueType
var darkValue: ValueType
public init(_ lightValue: ValueType = ValueType.self, _ darkValue: ValueType = ValueType.self) {
self.lightValue = lightValue
self.darkValue = darkValue
}
public func getValue(_ object: Any) -> ValueType {
guard let surfaceable = object as? Surfaceable else {
assertionFailure("Self doesn't confirms to Surfaceable")
return lightValue
}
return surfaceable.surface == .light ? lightValue : darkValue
}
}