114 lines
4.4 KiB
Swift
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
|
|
}
|
|
}
|