93 lines
3.8 KiB
Swift
93 lines
3.8 KiB
Swift
//
|
|
// 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<CGFloat> { get set }
|
|
///Shadow Offset configuration for light and dark surfaces
|
|
var shadowOffsetConfiguration: SurfaceConfigurationValue<CGSize> { get set }
|
|
///Shadow Radius configuration for light and dark surfaces
|
|
var shadowRadiusConfiguration: SurfaceConfigurationValue<CGFloat> { 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.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" }
|
|
}
|
|
|
|
//Helper variables to get gradient & shadow layers. These are exposed to update frame of layers when view's frame is updated.
|
|
var dropShadowLayers: [CALayer]? { layer.sublayers?.filter { $0.name == "dropShadowLayer" } }
|
|
var gradientLayers: [CAGradientLayer]? { layer.sublayers?.filter { $0.name == "gradientLayer" } as? [CAGradientLayer] }
|
|
}
|