TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

How to add inner and outer shadows for such a shape?

Forums > Swift

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.

Image

result

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.

   

Hacking with Swift is sponsored by Superwall.

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.