Reputation: 725
I was trying to add multiple shadows to my UIButton. The two shadows were added as you can see in the image. However, they hide the title and background colour of UIButton. Why is this happening? So, has the order of the layers become bottomLayer, topLayer, text and background?
The actual result
The expected Result
This is how my UIButton class looks.
class PrimaryButton: UIButton {
let cornerRadius: CGFloat = 10
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init() {
self.init(frame: .zero)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
addDropShadow()
}
private func configure() {
backgroundColor = .white;
layer.cornerRadius = cornerRadius
setTitle("Get Followers", for: .normal)
setTitleColor(Colours.buttonTextColour, for: .normal)
}
private func addDropShadow() {
let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))
layer.addSublayer(topLayer)
layer.addSublayer(bottomLayer)
}
private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer {
let shadowLayer = CALayer()
shadowLayer.masksToBounds = false
shadowLayer.shadowColor = color.cgColor
shadowLayer.shadowOpacity = 1
shadowLayer.shadowOffset = offset
shadowLayer.shadowRadius = 10
shadowLayer.shouldRasterize = true
shadowLayer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).cgPath
return shadowLayer
}
}
Upvotes: 1
Views: 1167
Reputation: 109
I was able to solve the problem as follows:
Instead of adding the layers with the addSublayer(_ layer: CALayer)
method, I used the insertSublayer(_ layer: CALayer, at idx: UInt32)
method.
private func addDropShadow() {
let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))
// Modified
layer.insertSublayer(topLayer, at: 0)
layer.insertSublayer(bottomLayer, at: 0)
}
Also, in your createShadowLayer
method, instead of CALayer, I returned a CAShapeLayer.
private func createShadowLayer(color: UIColor, offset: CGSize) -> CAShapeLayer {
// Modified
let shadowLayer = CAShapeLayer()
shadowLayer.path = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.cornerRadius).cgPath
shadowLayer.fillColor = self.backgroundColor?.cgColor
shadowLayer.shadowPath = shadowLayer.path
// shadowLayer.masksToBounds = false
shadowLayer.shadowColor = color.cgColor
shadowLayer.shadowOpacity = 1
shadowLayer.shadowOffset = offset
shadowLayer.shadowRadius = 10
// shadowLayer.shouldRasterize = true
return shadowLayer
}
I don't know if either change is essential. But that's how it worked for me :)
Upvotes: 1
Reputation: 379
Hello below code will help you, I got exact result what you want in button shadow
just replace some function with my code,
Your code:
override func layoutSubviews() {
super.layoutSubviews()
addDropShadow()
}
Replace it with my code:
override func layoutSubviews() {
super.layoutSubviews()
addDropShadow(color: UIColor.red, offset: CGSize(width: -6, height: -6), btnLayer: self.layer)
addDropShadow(color: UIColor.blue, offset: CGSize(width: 6, height: 6), btnLayer: self.layer)
}
Your code:
private func addDropShadow() {
let topLayer = createShadowLayer(color: Colours.shadowWhite, offset: CGSize(width: -6, height: -6))
let bottomLayer = createShadowLayer(color: Colours.shadowBlack, offset: CGSize(width: 6, height: 6))
layer.addSublayer(topLayer)
layer.addSublayer(bottomLayer)
}
private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer {
let shadowLayer = CALayer()
shadowLayer.masksToBounds = false
shadowLayer.shadowColor = color.cgColor
shadowLayer.shadowOpacity = 1
shadowLayer.shadowOffset = offset
shadowLayer.shadowRadius = 10
shadowLayer.shouldRasterize = true
shadowLayer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: 10).cgPath
return shadowLayer
}
Replace it with below code:
private func addDropShadow(color: UIColor, offset: CGSize, btnLayer : CALayer)
{
btnLayer.masksToBounds = false
btnLayer.shadowColor = color.cgColor
btnLayer.shadowOpacity = 1
btnLayer.shadowOffset = offset
btnLayer.shadowRadius = 10
}
no need to you private func createShadowLayer(color: UIColor, offset: CGSize) -> CALayer
you can remove that function.
and make sure your button type is custom
Upvotes: 0