Merge branch 'feature/tileContainer' into 'develop'
TileContainer VDS changes See merge request BPHV_MIPS/vds_ios!154
This commit is contained in:
commit
8f9ecce1c1
@ -14,6 +14,8 @@
|
||||
44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; };
|
||||
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
|
||||
5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; };
|
||||
7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */; };
|
||||
71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */; };
|
||||
71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; };
|
||||
EA0B18022A9E236900F2D0CD /* SelectorGroupBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18012A9E236900F2D0CD /* SelectorGroupBase.swift */; };
|
||||
EA0B18052A9E2D2D00F2D0CD /* SelectorBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0B18032A9E2D2D00F2D0CD /* SelectorBase.swift */; };
|
||||
@ -178,6 +180,8 @@
|
||||
44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
||||
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
|
||||
5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
|
||||
7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TileContainerChangeLog.txt; 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>"; };
|
||||
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>"; };
|
||||
@ -556,6 +560,7 @@
|
||||
EA3361B7288B2AAA0071C351 /* ViewProtocol.swift */,
|
||||
EAB1D2CC28ABE76000DAE764 /* Withable.swift */,
|
||||
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */,
|
||||
71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
@ -644,6 +649,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EA5E304B294CBDD00082B959 /* TileContainer.swift */,
|
||||
7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */,
|
||||
);
|
||||
path = TileContainer;
|
||||
sourceTree = "<group>";
|
||||
@ -936,6 +942,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EAEEECA42B1F934600531FC2 /* IconChangeLog.txt in Resources */,
|
||||
7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */,
|
||||
EA3362042891E14D0071C351 /* VerizonNHGeTX-Bold.otf in Resources */,
|
||||
71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */,
|
||||
EAEEECA72B1F952000531FC2 /* TabsChangeLog.txt in Resources */,
|
||||
@ -992,6 +999,7 @@
|
||||
EAB2376229E9880400AABE9A /* TrailingTooltipLabel.swift in Sources */,
|
||||
EAB2376A29E9E59100AABE9A /* TooltipLaunchable.swift in Sources */,
|
||||
EAB2375D29E8789100AABE9A /* Tooltip.swift in Sources */,
|
||||
71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */,
|
||||
EA0D1C452A6AD73000E5C127 /* RawRepresentable.swift in Sources */,
|
||||
EA985C23296E033A00F2FF2E /* TextArea.swift in Sources */,
|
||||
EAF7F0B3289B1ADC00B287F5 /* ActionLabelAttribute.swift in Sources */,
|
||||
|
||||
@ -454,9 +454,9 @@ open class ButtonIcon: Control, Changeable, FormFieldable {
|
||||
}
|
||||
|
||||
if let dropshadowable = currentConfig as? Dropshadowable {
|
||||
addDropShadow(config: dropshadowable)
|
||||
addDropShadow(dropshadowable)
|
||||
} else {
|
||||
removeDropShadow()
|
||||
removeDropShadows()
|
||||
}
|
||||
|
||||
badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2
|
||||
@ -530,37 +530,11 @@ extension ButtonIcon: AppleGuidelinesTouchable {
|
||||
}
|
||||
}
|
||||
|
||||
extension UIView {
|
||||
fileprivate func addDropShadow(config: Dropshadowable) {
|
||||
layer.masksToBounds = false
|
||||
layer.shadowColor = config.shadowColorConfiguration.getColor(self).cgColor
|
||||
layer.shadowOpacity = Float(config.shadowOpacity)
|
||||
layer.shadowOffset = config.shadowOffset
|
||||
layer.shadowRadius = config.shadowRadius
|
||||
layer.shouldRasterize = true
|
||||
layer.rasterizationScale = UIScreen.main.scale
|
||||
layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius).cgPath
|
||||
}
|
||||
|
||||
fileprivate func removeDropShadow() {
|
||||
layer.shadowOpacity = 0
|
||||
layer.shadowRadius = 0
|
||||
layer.shadowPath = nil
|
||||
}
|
||||
}
|
||||
|
||||
private protocol Borderable {
|
||||
var borderWidth: CGFloat { get set }
|
||||
var borderColorConfiguration: AnyColorable { get set }
|
||||
}
|
||||
|
||||
private protocol Dropshadowable {
|
||||
var shadowColorConfiguration: AnyColorable { get set }
|
||||
var shadowOpacity: CGFloat { get set }
|
||||
var shadowOffset: CGSize { get set }
|
||||
var shadowRadius: CGFloat { get set }
|
||||
}
|
||||
|
||||
private protocol Configuration {
|
||||
var kind: ButtonIcon.Kind { get set }
|
||||
var surfaceType: ButtonIcon.SurfaceType { get set }
|
||||
|
||||
@ -32,20 +32,36 @@ open class TileContainer: Control {
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
/// Enum used to describe the background color choices used for this component.
|
||||
public enum BackgroundColor: String, CaseIterable {
|
||||
public enum BackgroundColor: Equatable {
|
||||
|
||||
case primary
|
||||
case secondary
|
||||
case white
|
||||
case black
|
||||
case gray
|
||||
case transparent
|
||||
case custom(String)
|
||||
|
||||
private var reflectedValue: String { String(reflecting: self) }
|
||||
|
||||
public static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs.reflectedValue == rhs.reflectedValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum used to describe the background effect choices used for this component.
|
||||
public enum BackgroundEffect {
|
||||
case transparency
|
||||
case gradient(String, String)
|
||||
case none
|
||||
}
|
||||
|
||||
/// Enum used to describe the padding choices used for this component.
|
||||
public enum Padding: String, CaseIterable {
|
||||
public enum Padding {
|
||||
case padding2X
|
||||
case padding4X
|
||||
case padding6X
|
||||
case padding8X
|
||||
case padding12X
|
||||
case custom(CGFloat)
|
||||
|
||||
public var value: CGFloat {
|
||||
switch self {
|
||||
@ -59,6 +75,8 @@ open class TileContainer: Control {
|
||||
return VDSLayout.Spacing.space8X.value
|
||||
case .padding12X:
|
||||
return VDSLayout.Spacing.space12X.value
|
||||
case .custom(let padding):
|
||||
return padding
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -106,8 +124,11 @@ open class TileContainer: Control {
|
||||
open var aspectRatio: AspectRatio = .ratio1x1 { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Sets the background color for the component.
|
||||
open var color: BackgroundColor = .white { didSet { setNeedsUpdate() } }
|
||||
open var color: BackgroundColor = .secondary { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Sets the background effect for the component.
|
||||
open var backgroundEffect: BackgroundEffect = .none { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// Sets the inside padding for the component
|
||||
open var padding: Padding = .padding4X { didSet { setNeedsUpdate() } }
|
||||
|
||||
@ -165,6 +186,7 @@ open class TileContainer: Control {
|
||||
private let cornerRadius = VDSFormControls.borderradius * 2
|
||||
|
||||
private var backgroundColorConfiguration = BackgroundColorConfiguration()
|
||||
private var dropshadowConfiguration = DropshadowConfiguration()
|
||||
|
||||
private var borderColorConfiguration = SurfaceColorConfiguration().with {
|
||||
$0.lightColor = VDSColor.elementsLowcontrastOnlight
|
||||
@ -201,24 +223,20 @@ open class TileContainer: Control {
|
||||
addSubview(highlightView)
|
||||
|
||||
widthConstraint = layoutGuide.widthAnchor.constraint(equalToConstant: 0)
|
||||
widthConstraint?.priority = .defaultHigh
|
||||
|
||||
heightGreaterThanConstraint = layoutGuide.heightAnchor.constraint(greaterThanOrEqualToConstant: 44.0)
|
||||
heightGreaterThanConstraint?.isActive = false
|
||||
|
||||
heightConstraint = layoutGuide.heightAnchor.constraint(equalToConstant: 0)
|
||||
heightConstraint?.priority = .defaultHigh
|
||||
|
||||
backgroundImageView.pin(layoutGuide)
|
||||
backgroundImageView.isUserInteractionEnabled = false
|
||||
backgroundImageView.isHidden = true
|
||||
|
||||
containerView.backgroundColor = .clear
|
||||
|
||||
containerTopConstraint = containerView.pinTop(anchor: layoutGuide.topAnchor, constant: padding.value)
|
||||
containerBottomConstraint = containerView.pinBottom(anchor: layoutGuide.bottomAnchor, constant: padding.value)
|
||||
containerBottomConstraint = layoutGuide.pinBottom(anchor: containerView.bottomAnchor, constant: padding.value)
|
||||
containerLeadingConstraint = containerView.pinLeading(anchor: layoutGuide.leadingAnchor, constant: padding.value)
|
||||
containerTrailingConstraint = containerView.pinTrailing(anchor: layoutGuide.trailingAnchor, constant: padding.value)
|
||||
containerTrailingConstraint = layoutGuide.pinTrailing(anchor: containerView.trailingAnchor, constant: padding.value)
|
||||
|
||||
highlightView.pin(layoutGuide)
|
||||
highlightView.isHidden = true
|
||||
@ -228,7 +246,6 @@ open class TileContainer: Control {
|
||||
layer.cornerRadius = cornerRadius
|
||||
backgroundImageView.layer.cornerRadius = cornerRadius
|
||||
highlightView.layer.cornerRadius = cornerRadius
|
||||
|
||||
}
|
||||
|
||||
/// Resets to default settings.
|
||||
@ -268,8 +285,8 @@ open class TileContainer: Control {
|
||||
|
||||
containerTopConstraint?.constant = padding.value
|
||||
containerLeadingConstraint?.constant = padding.value
|
||||
containerBottomConstraint?.constant = -padding.value
|
||||
containerTrailingConstraint?.constant = -padding.value
|
||||
containerBottomConstraint?.constant = padding.value
|
||||
containerTrailingConstraint?.constant = padding.value
|
||||
|
||||
if let width, aspectRatio == .none && height == nil{
|
||||
widthConstraint?.constant = width
|
||||
@ -293,6 +310,12 @@ open class TileContainer: Control {
|
||||
widthConstraint?.isActive = false
|
||||
heightConstraint?.isActive = false
|
||||
}
|
||||
if showDropShadows, surface == .light {
|
||||
addDropShadow(dropshadowConfiguration)
|
||||
} else {
|
||||
removeDropShadows()
|
||||
}
|
||||
applyBackgroundEffects()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -310,6 +333,36 @@ open class TileContainer: Control {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Methods
|
||||
//--------------------------------------------------
|
||||
|
||||
private func applyBackgroundEffects() {
|
||||
let color = backgroundColorConfiguration.getColor(self)
|
||||
var alphaConfiguration: CGFloat = 1.0
|
||||
let imageFallbackColor = imageFallbackColorConfiguration.getColor(self)
|
||||
switch backgroundEffect {
|
||||
case .transparency:
|
||||
alphaConfiguration = 0.8
|
||||
removeGradientLayer()
|
||||
case .gradient(let firstColor, let secondColor):
|
||||
alphaConfiguration = 1.0
|
||||
addGradientLayer(with: UIColor(hexString: firstColor), secondColor: UIColor(hexString: secondColor))
|
||||
backgroundImageView.isHidden = true
|
||||
backgroundImageView.alpha = 1.0
|
||||
case .none:
|
||||
alphaConfiguration = 1.0
|
||||
removeGradientLayer()
|
||||
}
|
||||
if let backgroundImage {
|
||||
backgroundImageView.image = backgroundImage
|
||||
backgroundImageView.isHidden = false
|
||||
backgroundImageView.alpha = alphaConfiguration
|
||||
backgroundColor = imageFallbackColor.withAlphaComponent(alphaConfiguration)
|
||||
} else {
|
||||
backgroundImageView.isHidden = true
|
||||
backgroundImageView.alpha = 1.0
|
||||
backgroundColor = color.withAlphaComponent(alphaConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
private func ratioSize(for width: CGFloat) -> CGSize {
|
||||
var height: CGFloat = width
|
||||
|
||||
@ -343,22 +396,40 @@ open class TileContainer: Control {
|
||||
}
|
||||
|
||||
extension TileContainer {
|
||||
class BackgroundColorConfiguration: ObjectColorable {
|
||||
|
||||
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
|
||||
|
||||
let primaryColorConfig = SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryDark)
|
||||
let secondaryColorConfig = SurfaceColorConfiguration(VDSColor.backgroundSecondaryLight, VDSColor.backgroundSecondaryDark)
|
||||
let grayColorConfig = SurfaceColorConfiguration(VDSColor.backgroundSecondaryLight, VDSColor.backgroundSecondaryDark)
|
||||
let whiteColorConfig = SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteWhite)
|
||||
let blackColorConfig = SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack)
|
||||
|
||||
required init() { }
|
||||
|
||||
|
||||
func getColor(_ object: TileContainer) -> UIColor {
|
||||
switch object.color {
|
||||
|
||||
case .primary:
|
||||
primaryColorConfig.getColor(object.surface)
|
||||
case .secondary:
|
||||
secondaryColorConfig.getColor(object.surface)
|
||||
case .white:
|
||||
return VDSColor.backgroundPrimaryLight
|
||||
whiteColorConfig.getColor(object.surface)
|
||||
case .black:
|
||||
return VDSColor.backgroundPrimaryDark
|
||||
case .gray:
|
||||
return VDSColor.backgroundSecondaryLight
|
||||
case .transparent:
|
||||
return UIColor.clear
|
||||
blackColorConfig.getColor(object.surface)
|
||||
case .custom(let hexCode):
|
||||
UIColor(hexString: hexCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
90
VDS/Components/TileContainer/TileContainerChangeLog.txt
Normal file
90
VDS/Components/TileContainer/TileContainerChangeLog.txt
Normal file
@ -0,0 +1,90 @@
|
||||
MM/DD/YYYY
|
||||
----------------
|
||||
|
||||
02/01/2022
|
||||
----------------
|
||||
- ACTION | Migrated Spec file from working file into VDS Brand 3.0 Core SPECs & Test App.
|
||||
|
||||
02/02/2022
|
||||
----------------
|
||||
- Elements | Added option for user to manually define a custom Padding valueElements.
|
||||
- Elements | Removed option for 40px Padding
|
||||
- Elements | Added background options of Hex code and Transparency.
|
||||
|
||||
02/07/2022
|
||||
----------------
|
||||
- Anatomy | Updated descriptions to simplify. (Removed “Tile” from many)
|
||||
|
||||
02/08/2022
|
||||
----------------
|
||||
- Elements | Background color section updated
|
||||
- Elements | Removed option for 20px Padding value
|
||||
- Configurations | Surface section added
|
||||
- Configurations | Multiple sections updated
|
||||
- Behaviors | Interaction section added
|
||||
- States | Multiple sections updated/moved
|
||||
- ACTION | Sent to Accessibility Team to review
|
||||
|
||||
02/14/2022
|
||||
----------------
|
||||
- ACTION | Received sign off from Accessibility
|
||||
- ACTION | Sent to Talia for design review
|
||||
|
||||
02/21/2022
|
||||
----------------
|
||||
- Elements | Background colors and tokens updated.
|
||||
- ACTION | Ready for dev review.
|
||||
|
||||
02/22/2022
|
||||
----------------
|
||||
- Elements | Background names updated to infer surface prop selection.
|
||||
- ACTION | Web dev handoff completed.
|
||||
|
||||
12/15/2022
|
||||
----------------
|
||||
- States | Android drop shadow specs added, along with screenshot to the right of specs.
|
||||
- States | Added "(web only)" to any instance of "keyboard focus".
|
||||
- States | Replaced focus border pixel and style & spacing values with tokens.
|
||||
- Elements | Updated border color values to use element tokens.
|
||||
- Configurations | Updated border and drop shadow section titles to “Show border” and “Show drop shadow.”
|
||||
|
||||
01/18/2023
|
||||
----------------
|
||||
- Anatomy | Updated item #2 to “Padding” from “Container Internal Padding”
|
||||
|
||||
05/11/2023
|
||||
----------------
|
||||
- Removed showdropshadow prop from Configurations (dropshadow will be on automatically now for Surface=Light)
|
||||
- Updated states frame to remove states featuring dropshadow suppression, clarified state names, and removed inaccurate dev notes.
|
||||
|
||||
06/15/2023
|
||||
----------------
|
||||
- Added showDropShadow prop back into Configurations.
|
||||
- Moved Padding to Configurations
|
||||
|
||||
11/09/2023
|
||||
----------------
|
||||
- Updated showBorder section to match API prop names/values.
|
||||
- Moved Padding to Configurations.
|
||||
|
||||
11/20/2023
|
||||
----------------
|
||||
- Added corner radius token in the Anatomy
|
||||
- Updated visuals to reflect new corner radius value - 12px
|
||||
- Updated focus border corner radius to 14px
|
||||
- View changes
|
||||
|
||||
11/27/2023
|
||||
----------------
|
||||
- Updated “border radius” to “corner radius” in Anatomy
|
||||
- Updated “focus border radius” to “focus corner radius” in States
|
||||
- View changes
|
||||
|
||||
12/14/2023
|
||||
----------------
|
||||
- Added backgroundColor configuration section, removed Background Colors element section
|
||||
- Added secondary, primary backgroundColor options
|
||||
- Simplified backgroundImage section to remove backgroundColor example
|
||||
- Added background property section, with examples
|
||||
- Deprecated the gray backgroundColor option
|
||||
- View changes
|
||||
64
VDS/Protocols/Dropshadowable.swift
Normal file
64
VDS/Protocols/Dropshadowable.swift
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// 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" }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user