Merge branch 'develop' into feature/pagination
This commit is contained in:
commit
899e595dea
@ -24,6 +24,10 @@
|
||||
71FC86DC2B96F4C800700965 /* PaginationCellItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86DB2B96F4C800700965 /* PaginationCellItem.swift */; };
|
||||
71FC86E22B97483000700965 /* Clamping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86E12B97483000700965 /* Clamping.swift */; };
|
||||
71FC86E42B9841AC00700965 /* PaginationFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86E32B9841AC00700965 /* PaginationFlowLayout.swift */; };
|
||||
71BFA70A2B7F70E6000DCE33 /* DropShadowable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BFA7092B7F70E6000DCE33 /* DropShadowable.swift */; };
|
||||
71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; };
|
||||
71FC86DE2B9738B900700965 /* SurfaceConfigurationValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */; };
|
||||
71FC86E02B973AE500700965 /* DropShadowConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */; };
|
||||
EA0B18022A9E236900F2D0CD /* SelectorGroupBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */; };
|
||||
EA0B18052A9E2D2D00F2D0CD /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */; };
|
||||
EA0B18062A9E2D2D00F2D0CD /* SelectorItemBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18042A9E2D2D00F2D0CD /* SelectorItemBase.swift */; };
|
||||
@ -198,6 +202,10 @@
|
||||
71FC86DB2B96F4C800700965 /* PaginationCellItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationCellItem.swift; sourceTree = "<group>"; };
|
||||
71FC86E12B97483000700965 /* Clamping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clamping.swift; sourceTree = "<group>"; };
|
||||
71FC86E32B9841AC00700965 /* PaginationFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationFlowLayout.swift; sourceTree = "<group>"; };
|
||||
71BFA7092B7F70E6000DCE33 /* DropShadowable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropShadowable.swift; sourceTree = "<group>"; };
|
||||
71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NotificationChangeLog.txt; sourceTree = "<group>"; };
|
||||
71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SurfaceConfigurationValue.swift; sourceTree = "<group>"; };
|
||||
71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropShadowConfiguration.swift; sourceTree = "<group>"; };
|
||||
EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorGroupBase.swift; sourceTree = "<group>"; };
|
||||
EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorBase.swift; sourceTree = "<group>"; };
|
||||
EA0B18042A9E2D2D00F2D0CD /* SelectorItemBase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SelectorItemBase.swift; sourceTree = "<group>"; };
|
||||
@ -589,7 +597,7 @@
|
||||
EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */,
|
||||
EAB1D2CC28ABE76000DAE764 /* Withable.swift */,
|
||||
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */,
|
||||
71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */,
|
||||
71BFA7092B7F70E6000DCE33 /* DropShadowable.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
@ -609,6 +617,8 @@
|
||||
children = (
|
||||
EA3361BC288B2C760071C351 /* TypeAlias.swift */,
|
||||
71FC86E12B97483000700965 /* Clamping.swift */,
|
||||
71FC86DD2B9738B900700965 /* SurfaceConfigurationValue.swift */,
|
||||
71FC86DF2B973AE500700965 /* DropShadowConfiguration.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
@ -1034,7 +1044,7 @@
|
||||
EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */,
|
||||
EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */,
|
||||
EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */,
|
||||
71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */,
|
||||
71BFA70A2B7F70E6000DCE33 /* DropShadowable.swift in Sources */,
|
||||
EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */,
|
||||
EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */,
|
||||
71FC86E22B97483000700965 /* Clamping.swift in Sources */,
|
||||
@ -1061,6 +1071,7 @@
|
||||
EAC846F3294B95CE00F685BA /* ButtonGroupCollectionViewCell.swift in Sources */,
|
||||
EAF7F0952899861000B287F5 /* CheckboxItem.swift in Sources */,
|
||||
EA985BE82968951C00F2FF2E /* TileletTitleModel.swift in Sources */,
|
||||
71FC86DE2B9738B900700965 /* SurfaceConfigurationValue.swift in Sources */,
|
||||
EA297A5529FB07760031ED56 /* TooltipLabelAttribute.swift in Sources */,
|
||||
EA985BEA29689B6D00F2FF2E /* TileletSubTitleModel.swift in Sources */,
|
||||
EA3361C9289054C50071C351 /* Surfaceable.swift in Sources */,
|
||||
@ -1133,6 +1144,7 @@
|
||||
EAB2376829E9992800AABE9A /* TooltipAlertViewController.swift in Sources */,
|
||||
EA33623E2892EE950071C351 /* UIDevice.swift in Sources */,
|
||||
EA985C692971B90B00F2FF2E /* IconSize.swift in Sources */,
|
||||
71FC86E02B973AE500700965 /* DropShadowConfiguration.swift in Sources */,
|
||||
EA985C672970C21600F2FF2E /* VDSLayout.swift in Sources */,
|
||||
EA3362302891EB4A0071C351 /* Font.swift in Sources */,
|
||||
EAF7F0AD289B142900B287F5 /* StrikeThroughLabelAttribute.swift in Sources */,
|
||||
|
||||
@ -232,19 +232,26 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
}()
|
||||
}
|
||||
|
||||
private struct LowContrastColorFillFloatingConfiguration: Configuration, Dropshadowable {
|
||||
private struct LowContrastColorFillFloatingConfiguration: Configuration, DropShadowableConfiguration {
|
||||
var kind: Kind = .lowContrast
|
||||
var surfaceType: SurfaceType = .colorFill
|
||||
var floating: Bool = true
|
||||
var backgroundColorConfiguration: AnyColorable = {
|
||||
SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable()
|
||||
}()
|
||||
var shadowColorConfiguration: AnyColorable = {
|
||||
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
}()
|
||||
var shadowOpacity: CGFloat = 0.16
|
||||
var shadowOffset: CGSize = .init(width: 0, height: 2)
|
||||
var shadowRadius: CGFloat = 4
|
||||
private let dropshadow1Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.12), CGFloat(0.22))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(10), CGFloat(12))
|
||||
}
|
||||
private let dropshadow2Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.05), CGFloat(0.15))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(4), CGFloat(6))
|
||||
}
|
||||
var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] }
|
||||
}
|
||||
|
||||
private struct LowContrastMediaConfiguration: Configuration, Borderable {
|
||||
@ -260,19 +267,26 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
}()
|
||||
}
|
||||
|
||||
private struct LowContrastMediaFloatingConfiguration: Configuration, Dropshadowable {
|
||||
private struct LowContrastMediaFloatingConfiguration: Configuration, DropShadowableConfiguration {
|
||||
var kind: Kind = .lowContrast
|
||||
var surfaceType: SurfaceType = .media
|
||||
var floating: Bool = true
|
||||
var backgroundColorConfiguration: AnyColorable = {
|
||||
SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable()
|
||||
}()
|
||||
var shadowColorConfiguration: AnyColorable = {
|
||||
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
}()
|
||||
var shadowOpacity: CGFloat = 0.16
|
||||
var shadowOffset: CGSize = .init(width: 0, height: 2)
|
||||
var shadowRadius: CGFloat = 4
|
||||
private let dropshadow1Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.12), CGFloat(0.22))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(10), CGFloat(12))
|
||||
}
|
||||
private let dropshadow2Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.05), CGFloat(0.15))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(4), CGFloat(6))
|
||||
}
|
||||
var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] }
|
||||
}
|
||||
|
||||
private struct HighContrastConfiguration: Configuration {
|
||||
@ -291,7 +305,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
}()
|
||||
}
|
||||
|
||||
private struct HighContrastFloatingConfiguration: Configuration, Dropshadowable {
|
||||
private struct HighContrastFloatingConfiguration: Configuration, DropShadowableConfiguration {
|
||||
var kind: Kind = .highContrast
|
||||
var surfaceType: SurfaceType = .colorFill
|
||||
var floating: Bool = true
|
||||
@ -305,12 +319,19 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
|
||||
}.eraseToAnyColorable()
|
||||
}()
|
||||
var shadowColorConfiguration: AnyColorable = {
|
||||
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
}()
|
||||
var shadowOpacity: CGFloat = 0.16
|
||||
var shadowOffset: CGSize = .init(width: 0, height: 2)
|
||||
var shadowRadius: CGFloat = 6
|
||||
private let dropshadow1Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.22), CGFloat(0.12))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 1), .init(width: 0, height: 1))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(12), CGFloat(10))
|
||||
}
|
||||
private let dropshadow2Configuration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
|
||||
$0.shadowOpacityConfiguration = SurfaceConfigurationValue(CGFloat(0.15), CGFloat(0.05))
|
||||
$0.shadowOffsetConfiguration = SurfaceConfigurationValue(.init(width: 0, height: 2), .init(width: 0, height: 2))
|
||||
$0.shadowRadiusConfiguration = SurfaceConfigurationValue(CGFloat(6), CGFloat(4))
|
||||
}
|
||||
var configurations: [DropShadowable] { [dropshadow1Configuration, dropshadow2Configuration] }
|
||||
}
|
||||
|
||||
private var badgeIndicatorDefaultSize: CGSize = .zero
|
||||
@ -322,7 +343,7 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
isAccessibilityElement = true
|
||||
accessibilityTraits = .image
|
||||
accessibilityTraits = .button
|
||||
accessibilityElements = [badgeIndicator]
|
||||
|
||||
//create a layoutGuide for the icon to key off of
|
||||
@ -452,12 +473,6 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
layer.borderColor = nil
|
||||
layer.borderWidth = 0
|
||||
}
|
||||
|
||||
if let dropshadowable = currentConfig as? Dropshadowable {
|
||||
addDropShadow(dropshadowable)
|
||||
} else {
|
||||
removeDropShadows()
|
||||
}
|
||||
|
||||
badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2
|
||||
badgeIndicatorCenterYConstraint?.constant = badgeIndicatorOffset.y + badgeIndicatorDefaultSize.height/2
|
||||
@ -467,6 +482,12 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
if showBadgeIndicator {
|
||||
updateExpandDirectionalConstraints()
|
||||
}
|
||||
|
||||
if let configurations = (currentConfig as? DropShadowableConfiguration)?.configurations {
|
||||
addDropShadows(configurations)
|
||||
} else {
|
||||
removeDropShadows()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -154,13 +154,13 @@ open class EntryFieldBase: Control, Changeable, FormFieldable {
|
||||
open var showError: Bool = false { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Whether or not to show the internal error
|
||||
internal var showInternalError: Bool = false { didSet { setNeedsUpdate() } }
|
||||
open internal(set) var hasInternalError: Bool = false { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Override UIControl state to add the .error state if showError is true.
|
||||
open override var state: UIControl.State {
|
||||
get {
|
||||
var state = super.state
|
||||
if showError || showInternalError {
|
||||
if showError || hasInternalError {
|
||||
state.insert(.error)
|
||||
}
|
||||
return state
|
||||
@ -380,7 +380,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldable {
|
||||
}
|
||||
|
||||
open func updateErrorLabel(){
|
||||
if showError, showInternalError, let errorText, let internalErrorText {
|
||||
if showError, hasInternalError, let errorText, let internalErrorText {
|
||||
errorLabel.text = [internalErrorText, errorText].joined(separator: "\n")
|
||||
errorLabel.surface = surface
|
||||
errorLabel.isEnabled = isEnabled
|
||||
@ -398,7 +398,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldable {
|
||||
icon.color = VDSColor.paletteBlack
|
||||
icon.surface = surface
|
||||
icon.isHidden = !isEnabled
|
||||
} else if showInternalError, let internalErrorText {
|
||||
} else if hasInternalError, let internalErrorText {
|
||||
errorLabel.text = internalErrorText
|
||||
errorLabel.surface = surface
|
||||
errorLabel.isEnabled = isEnabled
|
||||
|
||||
@ -247,16 +247,16 @@ open class TextArea: EntryFieldBase {
|
||||
let countStr = (count > maxLength ?? 0) ? ("-" + "\(count-(maxLength ?? 0))") : "\(count)"
|
||||
if let maxLength, maxLength > 0 {
|
||||
if count > maxLength {
|
||||
showInternalError = true
|
||||
hasInternalError = true
|
||||
internalErrorText = "You have exceeded the character limit."
|
||||
return countStr
|
||||
} else {
|
||||
showInternalError = false
|
||||
hasInternalError = false
|
||||
internalErrorText = nil
|
||||
return ("\(countStr)" + "/" + "\(maxLength)")
|
||||
}
|
||||
} else {
|
||||
showInternalError = false
|
||||
hasInternalError = false
|
||||
internalErrorText = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -184,9 +184,15 @@ open class TileContainer: Control {
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
private let cornerRadius = VDSFormControls.borderradius * 2
|
||||
|
||||
private var backgroundColorConfiguration = BackgroundColorConfiguration()
|
||||
private var dropshadowConfiguration = DropshadowConfiguration()
|
||||
private let dropShadowConfiguration = DropShadowConfiguration().with {
|
||||
$0.shadowColorConfiguration = SurfaceColorConfiguration().with {
|
||||
$0.lightColor = VDSColor.elementsPrimaryOnlight
|
||||
}.eraseToAnyColorable()
|
||||
$0.shadowOffsetConfiguration = .init(.init(width: 0, height: 6), .zero)
|
||||
$0.shadowRadiusConfiguration = .init(3.0, 0.0)
|
||||
$0.shadowOpacityConfiguration = .init(0.01, 0.0)
|
||||
}
|
||||
|
||||
private var borderColorConfiguration = SurfaceColorConfiguration().with {
|
||||
$0.lightColor = VDSColor.elementsLowcontrastOnlight
|
||||
@ -311,7 +317,7 @@ open class TileContainer: Control {
|
||||
heightConstraint?.isActive = false
|
||||
}
|
||||
if showDropShadows, surface == .light {
|
||||
addDropShadow(dropshadowConfiguration)
|
||||
addDropShadow(dropShadowConfiguration)
|
||||
} else {
|
||||
removeDropShadows()
|
||||
}
|
||||
@ -397,15 +403,6 @@ open class TileContainer: Control {
|
||||
|
||||
extension TileContainer {
|
||||
|
||||
struct DropshadowConfiguration: Dropshadowable {
|
||||
var shadowColorConfiguration: AnyColorable = SurfaceColorConfiguration().with {
|
||||
$0.lightColor = VDSColor.elementsPrimaryOnlight
|
||||
}.eraseToAnyColorable()
|
||||
var shadowOpacity: CGFloat = 0.01
|
||||
var shadowOffset: CGSize = .init(width: 0, height: 6)
|
||||
var shadowRadius: CGFloat = 3
|
||||
}
|
||||
|
||||
final class BackgroundColorConfiguration: ObjectColorable {
|
||||
|
||||
typealias ObjectType = TileContainer
|
||||
|
||||
89
VDS/Protocols/DropShadowable.swift
Normal file
89
VDS/Protocols/DropShadowable.swift
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// 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.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" }
|
||||
}
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
//
|
||||
// Dropshadowable.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Bandaru, Krishna Kishore on 16/02/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
protocol Dropshadowable {
|
||||
|
||||
var shadowColorConfiguration: AnyColorable { get set }
|
||||
var shadowOpacity: CGFloat { get set }
|
||||
var shadowOffset: CGSize { get set }
|
||||
var shadowRadius: CGFloat { get set }
|
||||
}
|
||||
|
||||
extension ViewProtocol where Self: UIView {
|
||||
|
||||
func addDropShadow(_ config: Dropshadowable) {
|
||||
removeDropShadows()
|
||||
layer.backgroundColor = backgroundColor?.cgColor
|
||||
layer.masksToBounds = false
|
||||
let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius)
|
||||
let shadowLayer = CALayer()
|
||||
shadowLayer.shadowPath = shadowPath.cgPath
|
||||
shadowLayer.frame = bounds
|
||||
shadowLayer.position = center
|
||||
shadowLayer.backgroundColor = UIColor.clear.cgColor
|
||||
shadowLayer.cornerRadius = layer.cornerRadius
|
||||
shadowLayer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor
|
||||
shadowLayer.shadowOpacity = Float(config.shadowOpacity)
|
||||
shadowLayer.shadowOffset = .init(width: config.shadowOffset.width, height: config.shadowOffset.height)
|
||||
shadowLayer.shadowRadius = config.shadowRadius
|
||||
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.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" }
|
||||
}
|
||||
}
|
||||
33
VDS/Utilities/DropShadowConfiguration.swift
Normal file
33
VDS/Utilities/DropShadowConfiguration.swift
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// DropShadowConfiguration.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Bandaru, Krishna Kishore on 05/03/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
DropShadowConfiguration confirms to DropShadowable where it has configurable properties required for drop shadow
|
||||
*/
|
||||
final class DropShadowConfiguration: DropShadowable, ObjectWithable {
|
||||
|
||||
typealias CGFloatConfigurationValue = SurfaceConfigurationValue<CGFloat>
|
||||
typealias CGSizeConfigurationValue = SurfaceConfigurationValue<CGSize>
|
||||
|
||||
///Shadow Color configuration for light and dark surfaces
|
||||
var shadowColorConfiguration: AnyColorable
|
||||
///Shadow Opacity configuration for light and dark surfaces
|
||||
var shadowOpacityConfiguration: CGFloatConfigurationValue
|
||||
///Shadow Offset configuration for light and dark surfaces
|
||||
var shadowOffsetConfiguration: CGSizeConfigurationValue
|
||||
///Shadow Radius configuration for light and dark surfaces
|
||||
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
|
||||
}
|
||||
}
|
||||
31
VDS/Utilities/SurfaceConfigurationValue.swift
Normal file
31
VDS/Utilities/SurfaceConfigurationValue.swift
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// SurfaceConfigurationValue.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Bandaru, Krishna Kishore on 05/03/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
SurfaceConfiguration is a type that holds the generic datatype for light surface & dark surface and returns the value based on the surface.
|
||||
*/
|
||||
struct SurfaceConfigurationValue<ValueType> {
|
||||
|
||||
var lightValue: ValueType
|
||||
var darkValue: ValueType
|
||||
|
||||
public init(_ lightValue: ValueType, _ darkValue: ValueType) {
|
||||
self.lightValue = lightValue
|
||||
self.darkValue = darkValue
|
||||
}
|
||||
|
||||
public init(value: ValueType) {
|
||||
self.lightValue = value
|
||||
self.darkValue = value
|
||||
}
|
||||
|
||||
public func value(for object: Surfaceable) -> ValueType {
|
||||
object.surface == .light ? lightValue : darkValue
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user