Skip to content

Instantly share code, notes, and snippets.

@Josscii
Last active July 30, 2021 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Josscii/edc2044b4ad07b71996299d0d5c0722c to your computer and use it in GitHub Desktop.
Save Josscii/edc2044b4ad07b71996299d0d5c0722c to your computer and use it in GitHub Desktop.
create inner shadow - forget original source
// use after view has been layout
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)
{
// 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 = .evenOdd
// 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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment