What's the best way to add a drop shadow to my UIView

前端 未结 7 1151
自闭症患者
自闭症患者 2020-12-04 05:20

I am trying to add a drop shadow to views that are layered on top of one another, the views collapse allowing content in other views to be seen, in this vein i want to keep

相关标签:
7条回答
  • 2020-12-04 05:43

    Try this:

    UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRect:view.bounds];
    view.layer.masksToBounds = NO;
    view.layer.shadowColor = [UIColor blackColor].CGColor;
    view.layer.shadowOffset = CGSizeMake(0.0f, 5.0f);
    view.layer.shadowOpacity = 0.5f;
    view.layer.shadowPath = shadowPath.CGPath;
    

    First of all: The UIBezierPath used as shadowPath is crucial. If you don't use it, you might not notice a difference at first, but the keen eye will observe a certain lag occurring during events like rotating the device and/or similar. It's an important performance tweak.

    Regarding your issue specifically: The important line is view.layer.masksToBounds = NO. It disables the clipping of the view's layer's sublayers that extend further than the view's bounds.

    For those wondering what the difference between masksToBounds (on the layer) and the view's own clipToBounds property is: There isn't really any. Toggling one will have an effect on the other. Just a different level of abstraction.


    Swift 2.2:

    override func layoutSubviews()
    {
        super.layoutSubviews()
    
        let shadowPath = UIBezierPath(rect: bounds)
        layer.masksToBounds = false
        layer.shadowColor = UIColor.blackColor().CGColor
        layer.shadowOffset = CGSizeMake(0.0, 5.0)
        layer.shadowOpacity = 0.5
        layer.shadowPath = shadowPath.CGPath
    }
    

    Swift 3:

    override func layoutSubviews()
    {
        super.layoutSubviews()
    
        let shadowPath = UIBezierPath(rect: bounds)
        layer.masksToBounds = false
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
        layer.shadowOpacity = 0.5
        layer.shadowPath = shadowPath.cgPath
    }
    
    0 讨论(0)
  • 2020-12-04 05:45

    Wasabii's answer in Swift 2.3:

    let shadowPath = UIBezierPath(rect: view.bounds)
    view.layer.masksToBounds = false
    view.layer.shadowColor = UIColor.blackColor().CGColor
    view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
    view.layer.shadowOpacity = 0.2
    view.layer.shadowPath = shadowPath.CGPath
    

    And in Swift 3/4/5:

    let shadowPath = UIBezierPath(rect: view.bounds)
    view.layer.masksToBounds = false
    view.layer.shadowColor = UIColor.black.cgColor
    view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
    view.layer.shadowOpacity = 0.2
    view.layer.shadowPath = shadowPath.cgPath
    

    Put this code in layoutSubviews() if you're using AutoLayout.

    In SwiftUI, this is all much easier:

    Color.yellow  // or whatever your view
        .shadow(radius: 3)
        .frame(width: 200, height: 100)
    
    0 讨论(0)
  • 2020-12-04 05:46

    You can create an extension for UIView to access these values in the design editor

    extension UIView{
    
        @IBInspectable var shadowOffset: CGSize{
            get{
                return self.layer.shadowOffset
            }
            set{
                self.layer.shadowOffset = newValue
            }
        }
    
        @IBInspectable var shadowColor: UIColor{
            get{
                return UIColor(cgColor: self.layer.shadowColor!)
            }
            set{
                self.layer.shadowColor = newValue.cgColor
            }
        }
    
        @IBInspectable var shadowRadius: CGFloat{
            get{
                return self.layer.shadowRadius
            }
            set{
                self.layer.shadowRadius = newValue
            }
        }
    
        @IBInspectable var shadowOpacity: Float{
            get{
                return self.layer.shadowOpacity
            }
            set{
                self.layer.shadowOpacity = newValue
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 05:53

    You can set shadow to your view from storyboard also

    0 讨论(0)
  • 2020-12-04 05:55

    On viewWillLayoutSubviews:

    override func viewWillLayoutSubviews() {
        sampleView.layer.masksToBounds =  false
        sampleView.layer.shadowColor = UIColor.darkGrayColor().CGColor;
        sampleView.layer.shadowOffset = CGSizeMake(2.0, 2.0)
        sampleView.layer.shadowOpacity = 1.0
    }
    

    Using Extension of UIView:

    extension UIView {
    
        func addDropShadowToView(targetView:UIView? ){
            targetView!.layer.masksToBounds =  false
            targetView!.layer.shadowColor = UIColor.darkGrayColor().CGColor;
            targetView!.layer.shadowOffset = CGSizeMake(2.0, 2.0)
            targetView!.layer.shadowOpacity = 1.0
        }
    }
    

    Usage:

    sampleView.addDropShadowToView(sampleView)
    
    0 讨论(0)
  • 2020-12-04 05:58

    The trick is defining the masksToBounds property of your view's layer properly:

    view.layer.masksToBounds = NO;
    

    and it should work.

    (Source)

    0 讨论(0)
提交回复
热议问题