Shadow left and right of UIView
Asked Answered
C

4

7

Hi i like to add an CALayer Shadow to an View where the shadow was left and right of the view the simplest way was:

someView.layer.shadowColor = [[UIColor blackColor] CGColor];
someView.layer.shadowOffset = CGSizeMake(0.0f,0.0f);
someView.layer.shadowOpacity = 1.0f;
someView.layer.shadowRadius = 10.0f;
someView.layer.shadowPath = [[UIBezierPath bezierPathWithRect:someView.bounds] CGPath];

but i will add a bigger shadow as like a shadow when i increase the shadowRadius it do not look good. How i can make a shadow that looks good at left and right.

Canaanite answered 8/1, 2013 at 16:19 Comment(0)
G
31

I think 10 is a pretty big shadow radius, try 3 or 4 instead, also opacity I usually use 0.7:

someView.layer.shadowColor = [[UIColor blackColor] CGColor];
someView.layer.shadowOffset = CGSizeMake(0.0f,0.0f);
someView.layer.shadowOpacity = 0.7f;
someView.layer.shadowRadius = 4.0f;

If you want the shadow only on left and right, then inset the rectangle on the top and bottom so the top and bottom shadow are hidden behind your view:

CGRect shadowRect = CGRectInset(someView.bounds, 0, 4);  // inset top/bottom
someView.layer.shadowPath = [[UIBezierPath bezierPathWithRect:shadowRect] CGPath];

I'm not really sure if that's what you wanted.

Governorship answered 8/1, 2013 at 16:34 Comment(5)
I have talked with my designer this shadow is to small. I need different x offsets on left and right.Canaanite
Amazing answer, But guys have somebody implemented this with rounded corners(more smooth), since this rect-like shadow looks bad. Any insights ? Thanks in advance ! :)Gerah
Use bezierPathWithRoundedRect insteadGovernorship
I'm not sure why this has so many votes. In my implementation, as expected, it prevents the side shadows from going all the way to the top and bottom of the sides.Delagarza
@Governorship I want inner shadow with specific side, like only top or top/right. Any suggestions ?Claycomb
S
8

swift 3.0 version

imageView.layer.shadowOpacity = 0.8
imageView.layer.shadowOffset = CGSize(width: 0, height: 3)
imageView.layer.shadowRadius = 4.0

let shadowRect: CGRect = imageView.bounds.insetBy(dx: 0, dy: 4)
imageView.layer.shadowPath = UIBezierPath(rect: shadowRect).cgPath
Stool answered 6/7, 2017 at 9:20 Comment(0)
R
0

progrmr's answer was very helpful, cheers!

I made a slide-out menu and I had a problem with the shadow surrounding my VC and disrupting the navigation bar. Turned out I had to inset the shadow layer.

Here's my solution using swift:

rightViewController!.view.layer.shadowOpacity = 0.8
rightViewController!.view.layer.shadowOffset = CGSizeMake(0, 3)
rightViewController!.view.layer.shadowRadius = 4.0

let shadowRect: CGRect = CGRectInset(rightViewController!.view.bounds, 0, 4);  // inset top/bottom
rightViewController!.view.layer.shadowPath = UIBezierPath(rect: shadowRect).CGPath
Rosemari answered 27/6, 2016 at 13:46 Comment(0)
L
0

I created a shadow that can be used at the top/bottom or left/right, without prejudice at all. No shadow will appear in the left/right if you choose top/bottom, and so on. I hope I helped. Here's the code:


import UIKit

class ViewController: UIViewController {
  
    
     override func viewDidLoad() {
        super.viewDidLoad()
        
        let imgView = UIImageView(frame: CGRect(x: self.view.bounds.midX - 150, y: self.view.bounds.midY - 150, width: 300, height: 300))
            
        imgView.contentMode = .scaleToFill
        imgView.image = UIImage(named: "name image")

        self.view.addSubview(imgView)
        //You can put left/right or top/bottom
        imgView.addShadow(sides: .leftRight, constant: 10, alpha: 5)

        
     }

}

extension UIView{
    
    func addShadow(sides: Sides, constant: Int, alpha: Int){
        if(constant > 0 && alpha > 0){
        switch sides {
            case .leftRight:
   
                let view = UIView(frame: CGRect(x: -CGFloat(constant), y: 0, width: self.bounds.width + CGFloat((constant * 2)), height: self.bounds.height))
                self.addSubview(view)

                addMask(sides: .leftRight, view: view, constant: constant, shadowRadius: alpha)
                
            case .topBottom:

                let view = UIView(frame: CGRect(x: 0, y: -CGFloat(constant), width: self.bounds.width , height: self.bounds.height + CGFloat(constant * 2)))
                self.addSubview(view)

                addMask(sides: .topBottom, view: view, constant: constant, shadowRadius: alpha)

            }
        }
    }
    
    private func addMask(sides:Sides, view: UIView, constant: Int, shadowRadius:Int){
        let mutablePath = CGMutablePath()
        let mask = CAShapeLayer()

        switch sides {
        case .leftRight:
            
            mutablePath.addRect(CGRect(x: -CGFloat(constant), y: 0, width: view.bounds.width, height: view.bounds.height))

            mutablePath.addRect(CGRect(x: CGFloat(constant) , y: 0, width: view.bounds.width , height: view.bounds.height))

            
        case .topBottom:
            
            mutablePath.addRect(CGRect(x: 0, y: -CGFloat(constant), width: view.bounds.width, height: view.bounds.height))

            mutablePath.addRect(CGRect(x: 0, y: CGFloat(constant) , width: view.bounds.width , height: view.bounds.height))
        }

        mask.path = mutablePath

        mask.fillRule = CAShapeLayerFillRule.evenOdd
        mask.fillColor  = UIColor(white:1.0, alpha: 0.2).cgColor
        view.layer.mask = mask
        view.layer.addSublayer(mask)
        mask.shadowColor = UIColor.black.cgColor
        mask.shadowRadius = CGFloat(shadowRadius)
        mask.shadowOpacity = 1.0
        mask.shadowOffset = CGSize(width: 0, height: 0)

    }
}

enum Sides{
    case leftRight
    case topBottom
}

You just need to call the extension UIView, which has the addShadow() function and pass the parameters you want.

enter image description here

enter image description here

Loera answered 5/5, 2021 at 18:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.