iOS add / remove shadow from a view

2020-06-08 15:00发布

问题:

I do not understand how to remove a shadow that was added to a view. I add to my view in initWithFrame a shadow in this way:

self.layer.borderWidth = 2;
self.layer.borderColor = [UIColor clearColor].CGColor;
self.backgroundColor = [UIColor greenColor];
[self.layer setCornerRadius:8.0f];
CALayer *layer = self.layer;
layer.shadowOffset = CGSizeMake(2, 2);
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.cornerRadius = 8.0f;
layer.shadowRadius = 3.0f;
layer.shadowOpacity = 0.80f;
layer.shadowPath = [[UIBezierPath bezierPathWithRect:layer.bounds] CGPath];

After in the execution of the app I want to remove the shadow from this view. I've tried using:

layer.hidden = YES;

or

self.layer.hidden = YES;

but this hides the view completely, not just the added shadow.

Is there a way to retrieve the added shadow from a view and then hide it? Thanks!

回答1:

I guess you could use the shadowOpacity property of your CALayer.

So this should work:

self.layer.shadowOpacity = 0;

See the CALayer's shadowOpacity documentation page

And to show your shadow use:

self.layer.shadowOpacity = 1.0;


回答2:

Sorry, not sure the correct way, but have you tried changing the properties of the layer shadow? For example, one of these;

 layer.shadowOffset = CGSizeMake(0, 0);
 layer.shadowColor = [[UIColor clearColor] CGColor];
 layer.cornerRadius = 0.0f;
 layer.shadowRadius = 0.0f;
 layer.shadowOpacity = 0.00f;


回答3:

Swift 4.2

I am using this in my code for labels and navigation bar.

extension UIView {

    func shadow(_ height: Int = 5) {
        self.layer.masksToBounds = false
        self.layer.shadowRadius = 4
        self.layer.shadowOpacity = 1
        self.layer.shadowColor = UIColor.gray.cgColor
        self.layer.shadowOffset = CGSize(width: 0 , height: height)
    }

    func removeShadow() {
        self.layer.shadowOffset = CGSize(width: 0 , height: 0)
        self.layer.shadowColor = UIColor.clear.cgColor
        self.layer.cornerRadius = 0.0
        self.layer.shadowRadius = 0.0
        self.layer.shadowOpacity = 0.0
    }
}


回答4:

the "layer" that you are trying to make hidden is the layer of the object that you are having a shadow to it's not a visible aspect.. only the objects with in the layer... it's rather confusing to conceptualize anyways, the only way to remove the shadow is to undo what you originally did, which was suggested above, there is no defined property that you can just toggle a bool and make the shadow go away



回答5:

Swift 5.+

My solution was to add a shadowBackgroundView, which has a removable shadowLayer. In this way I could easyly remove the layer without resetting the shadow properties.

class ViewController: UIViewController {

    private let shadowBackgroundView: UIView = {
        let view = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
        view.layer.masksToBounds = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        view.addSubview(shadowBackgroundView)

        // the view you want to add the shadow
        let dummyView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        dummyView.backgroundColor = .red
        shadowBackgroundView.addSubview(dummyView)

        let addShadowButton = UIButton(frame: CGRect(x: 100, y: 300, width: 140, height: 50))
        addShadowButton.backgroundColor = .blue
        addShadowButton.setTitle("Add Shadow", for: .normal)
        addShadowButton.addTarget(self, action: #selector(addShadow), for: .touchUpInside)

        let removeShadowButton = UIButton(frame: CGRect(x: 100, y: 450, width: 140, height: 50))
        removeShadowButton.backgroundColor = .blue
        removeShadowButton.setTitle("Remove Shadow", for: .normal)
        removeShadowButton.addTarget(self, action: #selector(removeShadow), for: .touchUpInside)

        view.addSubview(addShadowButton)
        view.addSubview(removeShadowButton)
    }

    @objc
    func addShadow() {
        let shadowLayer = CALayer()
        shadowLayer.name = "ShadowLayer"
        shadowLayer.shadowColor = UIColor.black.cgColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = .zero
        shadowLayer.shadowRadius = 10
        shadowLayer.shadowPath = UIBezierPath(rect: shadowBackgroundView.bounds).cgPath
        // Otherwise the shadow will appear above the dummyView
        shadowLayer.zPosition = -1
        shadowBackgroundView.layer.addSublayer(shadowLayer)
    }

    @objc
    func removeShadow() {
        // Alternatively, you could also create the shadowLayer as a property, so you could call shadowLayer.removeFromSuperLayer()
        shadowBackgroundView.layer.sublayers?.first { $0.name == "ShadowLayer" }?.removeFromSuperlayer()
    }
}

As a Note, for the UITableViewCell, you wouldnt need to add a shadowBackgroundView, but you could add the shadowLayer directly to cell.view.layer, which serves as the backgroundView for the cell.contentView.



标签: ios uiview