Search code examples
swiftuibuttonshadow

I need to remove inner shadow when I click a button


this is my extension that I use for add inner shadow into my button. i create all case where I want my shadow into the button or my view.

public extension UIView

{ // different inner shadow styles public enum innerShadowSide { case all, left, right, top, bottom, topAndLeft, topAndRight, bottomAndLeft, bottomAndRight, exceptLeft, exceptRight, exceptTop, exceptBottom }

// define function to add inner shadow
public func addInnerShadow(onSide: innerShadowSide, shadowColor: UIColor, shadowSize: CGFloat, cornerRadius: CGFloat = 0.0, shadowOpacity: Float) -> CAShapeLayer

{
    // define and set a shaow layer
    let shadowLayer = CAShapeLayer()
    shadowLayer.frame = bounds
    shadowLayer.shadowColor = shadowColor.cgColor
    shadowLayer.shadowOffset = CGSize(width: 0.0, height: 0.0)
    shadowLayer.shadowOpacity = shadowOpacity
    shadowLayer.shadowRadius = shadowSize
    shadowLayer.fillRule = kCAFillRuleEvenOdd

    // define shadow path
    let shadowPath = CGMutablePath()

    // define outer rectangle to restrict drawing area
    let insetRect = bounds.insetBy(dx: -shadowSize * 2.0, dy: -shadowSize * 2.0)

    // define inner rectangle for mask
    let innerFrame: CGRect = { () -> CGRect in
        switch onSide
        {

        case .all:
            return CGRect(x: 0.0, y: 0.0, width: frame.size.width, height: frame.size.height)
        case .left:
            return CGRect(x: 0.0, y: -shadowSize * 2.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 4.0)
        case .right:
            return CGRect(x: -shadowSize * 2.0, y: -shadowSize * 2.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 4.0)
        case .top:
            return CGRect(x: -shadowSize * 2.0, y: 0.0, width: frame.size.width + shadowSize * 4.0, height: frame.size.height + shadowSize * 2.0)
        case.bottom:
            return CGRect(x: -shadowSize * 2.0, y: -shadowSize * 2.0, width: frame.size.width + shadowSize * 4.0, height: frame.size.height + shadowSize * 2.0)
        case .topAndLeft:
            return CGRect(x: 0.0, y: 0.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 2.0)
        case .topAndRight:
            return CGRect(x: -shadowSize * 2.0, y: 0.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 2.0)
        case .bottomAndLeft:
            return CGRect(x: 0.0, y: -shadowSize * 2.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 2.0)
        case .bottomAndRight:
            return CGRect(x: -shadowSize * 2.0, y: -shadowSize * 2.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height + shadowSize * 2.0)
        case .exceptLeft:
            return CGRect(x: -shadowSize * 2.0, y: 0.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height)
        case .exceptRight:
            return CGRect(x: 0.0, y: 0.0, width: frame.size.width + shadowSize * 2.0, height: frame.size.height)
        case .exceptTop:
            return CGRect(x: 0.0, y: -shadowSize * 2.0, width: frame.size.width, height: frame.size.height + shadowSize * 2.0)
        case .exceptBottom:
            return CGRect(x: 0.0, y: 0.0, width: frame.size.width, height: frame.size.height + shadowSize * 2.0)
        }
    }()

    // add outer and inner rectangle to shadow path
    shadowPath.addRect(insetRect)
    shadowPath.addRect(innerFrame)

    // set shadow path as show layer's
    shadowLayer.path = shadowPath

    // add shadow layer as a sublayer
    layer.addSublayer(shadowLayer)

    // hide outside drawing area
    clipsToBounds = true

    return shadowLayer

}

} I use this code like this when I see for the first time my button: in this case I want to have the shadow into all my button and I use the black color.

var shadowLayer : CAShapeLayer?

            self.shadowLayer = okButton.addInnerShadow(onSide: UIView.innerShadowSide.all, shadowColor: UIColor.black, shadowSize: 10.0, shadowOpacity: 10.0)

I need to remove this inner shadow when I click my button into my function:

       @IBAction func btnAction(_ sender: DLRadioButton) {
    if sender.tag == 1
    {
        statoBici = "ok"
        print(statoBici)
        setConfermaButton()
        self.shadowLayer.removeFromSuperLayer()


    }

Solution

  • Modify your UIView function to return CAShapeLayer:

    public func addInnerShadow(onSide: innerShadowSide, shadowColor: UIColor, shadowSize: CGFloat, cornerRadius: CGFloat = 0.0, shadowOpacity: Float) -> CAShapeLayer
    {
    .
    .
    . 
      return shadowLayer
    }
    

    Then add a variable or member variable to your class:

    class ViewController: UIViewController {
      var shadowLayer : CAShapeLayer!
    
    
    
     override func viewDidLoad() {
        super.viewDidLoad()  
        self.shadowLayer = btnShadow.addInnerShadow(onSide: UIView.innerShadowSide.all, shadowColor: UIColor.black, shadowSize: 10.0, shadowOpacity: 10.0)
      }
    }
    

    And finally , remove the shadow layer from your button:

      @IBAction func btnAction(_ sender: Any) {
            if let btn = sender as? UIButton
            {
              if btn.tag == 1 {
                self.shadowLayer.removeFromSuperlayer()
              }
            }
          }
    

    enter image description here enter image description here