Draw a shadow shadow outside the UIView

Background

I have a UIView with the following properties:

  • alpha = 1
  • backgroundColor = white, with opacity 0.35
  • rounded corners
  • shadow

code

This is how I create the shadow: ( UIView extension)

 self.layer.masksToBounds = false self.layer.shadowColor = UIColor.darkGrayColor().CGColor self.layer.shadowOffset = CGSizeMake(0, 5) self.layer.shadowOpacity = 0.35 self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).CGPath 

results

The result is the following:

current result

... while I do not want to see a shadow under such a view:

desired result

Question

How can I draw a shadow outside of the view only so that it is not visible under it?

Thanks in advance!

+5
source share
2 answers

It may be a little more complicated than necessary, but here is one solution.

UIView following way:

 extension UIView { // Note: the method needs the view from which the context is taken as an argument. func dropShadow(superview: UIView) { // Get context from superview UIGraphicsBeginImageContext(self.bounds.size) superview.drawViewHierarchyInRect(CGRect(x: -self.frame.minX, y: -self.frame.minY, width: superview.bounds.width, height: superview.bounds.height), afterScreenUpdates: true) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() // Add a UIImageView with the image from the context as a subview let imageView = UIImageView(frame: self.bounds) imageView.image = image imageView.layer.cornerRadius = self.layer.cornerRadius imageView.clipsToBounds = true self.addSubview(imageView) // Bring the background color to the front, alternatively set it as UIColor(white: 1, alpha: 0.2) let brighter = UIView(frame: self.bounds) brighter.backgroundColor = self.backgroundColor ?? UIColor(white: 1, alpha: 0.2) brighter.layer.cornerRadius = self.layer.cornerRadius brighter.clipsToBounds = true self.addSubview(brighter) // Set the shadow self.layer.masksToBounds = false self.layer.shadowColor = UIColor.darkGrayColor().CGColor self.layer.shadowOffset = CGSizeMake(0, 5) self.layer.shadowOpacity = 0.35 self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).CGPath } } 

Usage, given that the background view is called view :

 let shadowView = UIView(frame: CGRect(x: 100, y: 100, width: 300, height: 200)) shadowView.layer.cornerRadius = 15.0 shadowView.dropShadow(view) view.addSubview(shadowView) 

The result is the following:

Uiview

Note. The dropShadow method may not be called from viewDidLoad , as this causes problems with the graphics context. So, use this method at the beginning of viewWillAppear for the result above.


Here is the code for the background view, just in case someone wants to test on the playgrounds:

 let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 400)) view.backgroundColor = UIColor.clearColor() let color1 = UIColor(hue: 0.39, saturation: 0.7, brightness: 1.0, alpha: 1.0).CGColor let color2 = UIColor(hue: 0.51, saturation: 0.9, brightness: 0.6, alpha: 1.0).CGColor let gradient = CAGradientLayer() gradient.frame = view.frame gradient.colors = [color1, color2] gradient.startPoint = CGPoint(x: 0, y: 0) gradient.endPoint = CGPoint(x: 1, y: 1) view.layer.insertSublayer(gradient, atIndex: 0) 
+5
source

This has been slightly adapted to the message found here. I did not know the specifics of your layer, so instead I created a circle located in the center of the screen. You can easily replace the circle with the specifications of your layer, and I believe that this will fix your problems. Feel free to comment on any further instructions! import UIKit

 class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() createOverlay(view.bounds) } func createOverlay(frame : CGRect) { let overlayView = UIView(frame: frame) overlayView.alpha = 0.6 overlayView.backgroundColor = UIColor.blackColor() self.view.addSubview(overlayView) let maskLayer = CAShapeLayer() let path = CGPathCreateMutable() let radius : CGFloat = 50.0 let xOffset : CGFloat = view.bounds.width / 2 let yOffset : CGFloat = view.bounds.height / 2 CGPathAddArc(path, nil, overlayView.frame.width - xOffset, yOffset, radius, 0.0, 2 * 3.14, false) CGPathAddRect(path, nil, CGRectMake(0, 0, overlayView.frame.width, overlayView.frame.height)) maskLayer.backgroundColor = UIColor.blackColor().CGColor maskLayer.path = path; maskLayer.fillRule = kCAFillRuleEvenOdd overlayView.layer.mask = maskLayer overlayView.clipsToBounds = true } } 

Photo Screenshot Simulator

0
source

All Articles