UIView Shadow Gradient

Viewed 5031

I have created a custom UIView in my iOS project that has a drop shadow. My aim is to apply the same gradient to the shadow as it is on the view's background.

Below is an example of how my current solid colour shadows look.

Shadow Example This is done through a subclass of UIView with the below code:

override func layoutSubviews() {
    let gradientLayer = layer as! CAGradientLayer
    gradientLayer.colors = [topColor.cgColor, bottomColor.cgColor]
    gradientLayer.startPoint = CGPoint(x: startPointX, y: startPointY)
    gradientLayer.endPoint = CGPoint(x: endPointX, y: endPointY)
    layer.cornerRadius = cornerRadius
    layer.shadowColor = shadowColor.cgColor
    layer.shadowOffset = CGSize(width: shadowX, height: shadowY)
    layer.shadowRadius = shadowBlur
    layer.shadowOpacity = 1

    let inset: CGFloat = bounds.width * 0.05
    layer.shadowPath = UIBezierPath(roundedRect: bounds.insetBy(dx: inset, dy: 0.0), cornerRadius: cornerRadius).cgPath
}

I have been playing around with creating a second gradient layer and masking it to the shadow but have had no luck. Please point me in the right direction!

3 Answers

Use my code for your requirement available in my gitRepo https://github.com/Krishnarjun-Banoth/BlurView/tree/master/Shadows

Step1: Just drag and drop BlurEffect.swift file in your project.

Step2: Then simply Use below View extension methods for each one your views individually.

  testView.applyGradient(colours: [UIColor.blue,UIColor.orange]) //pass your required colours.
  testView.blur(blurRadius: 5.0)

Note: Inspired from @Jacek Głazik answer and FlexMonkey's tutorial.

I believe @jacek is right, you're pushing the limit of what you can do with CALayer shadows (which isn't much to be honest)

The best things to do as jacek explain is to create your own shadow, though another CAGradientLayer applying Gaussian blur to act as a shadow.

Also, I don't believe placing your code inside the layoutSubviews is the most appropriate place. Once configured your layer won't need to change much, and thus it will be called a lot if your layout change a lot.

Usually if using a view coming from interface-builder, I would call this logic from awakeFromNib inside a dedicated configureBackgroundViews function for example.

Related