Good afternoon everyone.
There is no way I can make an inner and outer shadow for such a figure. I tried to create more rectangles with shadows applied, but the masks were cut off.
import UIKit
final class LoadingViewController: UIViewController {
// MARK: - Dependencies
var iterator: ILoadingIterator?
// MARK: - Private properties
private lazy var imageBackground = createImage()
private lazy var shape = createShape()
private lazy var gradient = createGradient()
private lazy var viewLoaderDropShadow = createView()
private lazy var viewLoader = createView()
private lazy var shapeMask = createMask()
private lazy var labelTitle = UILabel()
// MARK: - Initializator
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
// MARK: - Public methods
override func viewDidLoad() {
super.viewDidLoad()
setupConfiguration()
addUIView()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
setupLayout()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
// gradient.frame = viewLoader.frame
}
}
// MARK: - Add UIView.
private extension LoadingViewController {
/// Добавление элементов UIView в Controller.
func addUIView() {
let views: [UIView] = [
imageBackground,
viewLoaderDropShadow,
viewLoader
]
views.forEach(view.addSubview)
}
}
// MARK: - UI configuration.
private extension LoadingViewController {
/// Настройка UI элементов
func setupConfiguration() {
view.backgroundColor = FlatColor.Green.darkGreen
viewLoader.layer.insertSublayer(gradient, at: 0)
viewLoader.layer.cornerRadius = GlobalStyle.Radius.loader
viewLoader.clipsToBounds = true
viewLoader.layer.mask = shape
viewLoaderDropShadow.layer.cornerRadius = GlobalStyle.Radius.loader
viewLoaderDropShadow.backgroundColor = UIColor.red
viewLoaderDropShadow.layer.shadowOpacity = 1
viewLoaderDropShadow.layer.shadowRadius = 2
viewLoaderDropShadow.layer.shadowColor = UIColor.red.cgColor
viewLoaderDropShadow.layer.shadowOffset = CGSize(width: 10, height: 10)
viewLoaderDropShadow.clipsToBounds = true
// viewLoaderDropShadow.layer.mask = shapeMask
//
// maskForShadow.backgroundColor = UIColor.green
// maskForShadow.layer.shadowOpacity = 1
// maskForShadow.layer.shadowRadius = 2
// maskForShadow.layer.shadowColor = UIColor.red.cgColor
// maskForShadow.layer.shadowOffset = CGSize(width: 2, height: 2)
// maskForShadow.layer.mask = mask
// Настройка UILabel 'Название потока'
// labelTitle.text = "Repair flow."
// labelTitle.font = UIFont.systemFont(ofSize: 16)
// labelTitle.translatesAutoresizingMaskIntoConstraints = false
}
}
// MARK: - Add constraint.
private extension LoadingViewController {
/// Верстка элементов UI.
/// - Note: Добавление constraints для UIView элементов.
func setupLayout() {
let sizeLoader = GlobalStyle.Height.self
NSLayoutConstraint.activate([
imageBackground.topAnchor.constraint(equalTo: view.topAnchor),
imageBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor),
imageBackground.leftAnchor.constraint(equalTo: view.leftAnchor),
imageBackground.rightAnchor.constraint(equalTo: view.rightAnchor),
viewLoader.centerXAnchor.constraint(equalTo: view.centerXAnchor),
viewLoader.centerYAnchor.constraint(equalTo: view.centerYAnchor),
viewLoader.widthAnchor.constraint(equalToConstant: sizeLoader.heighLoader),
viewLoader.heightAnchor.constraint(equalToConstant: sizeLoader.heighLoader),
viewLoaderDropShadow.centerXAnchor.constraint(equalTo: view.centerXAnchor),
viewLoaderDropShadow.topAnchor.constraint(equalTo: viewLoader.bottomAnchor, constant: 10),
//viewLoaderDropShadow.centerYAnchor.constraint(equalTo: view.centerYAnchor),
viewLoaderDropShadow.widthAnchor.constraint(equalToConstant: sizeLoader.heighLoader),
viewLoaderDropShadow.heightAnchor.constraint(equalToConstant: sizeLoader.heighLoader),
])
}
}
// MARK: - UI Fabric.
private extension LoadingViewController {
func createImage() -> UIImageView {
let image = UIImage(named: "Images/Backgrounds/backgroundMask")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.alpha = 0.5
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}
func createView() -> UIView {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}
func createGradient() -> CAGradientLayer {
let gradient = CAGradientLayer()
gradient.frame = CGRect(
x: 0,
y: 0,
width: GlobalStyle.Height.heighLoader,
height: GlobalStyle.Height.heighLoader
)
gradient.startPoint = CGPoint(x: 0.5, y: 0.5)
gradient.endPoint = CGPoint(x: 1, y: 0.5)
gradient.colors = GradientColors.angularYellowGradient
gradient.type = .conic
return gradient
}
func createShape() -> CAShapeLayer {
let layer = CAShapeLayer()
let path = UIBezierPath(rect: CGRect(
x: 0,
y: 0,
width: GlobalStyle.Height.heighLoader,
height: GlobalStyle.Height.heighLoader
))
let maskPath = UIBezierPath(rect: CGRect(
x: (GlobalStyle.Height.heighLoader - GlobalStyle.Height.heightMask) / 2,
y: (GlobalStyle.Height.heighLoader - GlobalStyle.Height.heightMask) / 2,
width: GlobalStyle.Height.heightMask,
height: GlobalStyle.Height.heightMask
))
path.append(maskPath)
path.usesEvenOddFillRule = true
layer.path = path.cgPath
layer.fillRule = .evenOdd
return layer
}
func createMask() -> CAShapeLayer {
let layer = CAShapeLayer()
let path = CGMutablePath()
path.addRect(CGRect(
x: (GlobalStyle.Height.heighLoader - GlobalStyle.Height.heightMask) / 2,
y: (GlobalStyle.Height.heighLoader - GlobalStyle.Height.heightMask) / 2,
width: GlobalStyle.Height.heighLoader,
height: GlobalStyle.Height.heighLoader
))
layer.path = path
layer.fillRule = .evenOdd
return layer
}
}
// MARK: - UI Action.
// MARK: - Render logic.