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 RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

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.