A shadow is an image painted underneath and offset from a graphics object. It mimics the effect of a light source cast on the graphics object. Shadows are used to indicate layering and priority (for example when a modal alert is presented in front of others view). Also, they are used for cosmetic purposes (to improve control appearance).
CALayer has different properties for shadow configuration. The most significant are:
- shadowOpacity : the opacity of the layer’s shadow. The value of this property must be in the range 0.0 (invisible) to 1.0 (opaque). The default value of this property is 0.0.
- shadowColor : the color of the layer’s shadow. The type of this property is CGColor?, just like the backgroundColor and borderColor properties. The default value of this property is an opaque black color (colored shadows are rare in real life and can look a bit strange).
- shadowRadius : the blur radius used to render the layer’s shadow. A value of zero creates a hard-edged shadow that exactly matches the shape of the view. A larger value creates a soft-edged shadow that looks more natural. The default value of this property is 3.0.
- shadowOffset : the offset of the layer’s shadow. The type of this property is CGSize. Width controls the shadow’s horizontal offset, and the height controls its vertical offset. The default value of this property is (0.0, -3.0).
Also, CALayer has a shadow property. It assigns the NSShadow object as layer shadow. An instance of NSShadow created using the shadowColor, shadowOffset, shadowOpacity and shadowRadius properties of the view’s layer. The default value of this property is normally nil.
Assigning a new shadow object to this property sets the corresponding shadow-related properties on the view’s layer. It is important to note that if the view does not have a layer, setting the value of shadow property has no effect.
The layer’s shadow derives from the exact shape of its contents, not just the bounds and cornerRadius. To calculate the shape of the shadow, Core Animation looks at the backing image and sublayers (if exist). It uses these to create a shadow that perfectly matches the shape of the layer.
Important, you need to use a PNG image with an alpha component as backing image that includes an alpha mask.
Layer shadows have a limitation when combined with clipping. The shadow is usually drawn outside the layer bounds.
Example 1: masksToBounds property.
If you enable the masksToBounds property, the shadow will clip along with any other content that protrudes outside of the layer.
Look at the code below. Difference between two views is a value of the masksToBounds property. Value of this property on the left view set to false. A Right view set masksToBounds to true.
This behavior is understandable from a technical perspective. It is unlikely to be the effect that you wanted. If you want to clip the contents and cast a shadow, you need to use two layers: an outer layer that just draws the shadow and an inner that has masksToBounds enabled for clipping content. We need to update our code. Let’s do it!
Look at the picture below. We have a gorgeous shadow!
Example 2: Layer Masking.
You should know that mask is an optional layer whose alpha channel is used to mask the parent layer’s content. Layer mask also clips the shadow.
We have a simple layer with an image as contents. Also, we add a shadow. Look at the picture below.
We want to clip it using CAShapeLayer as mask.
Simple code example.
As you can see from the picture, the shadow is cropped. We need to change our code. Let’s do it!
And now we have a great shadow!
Also, you can read more about Layer Masking in my article.
So, we know that layer shadows are not always square. Shadow derives from the shape of the contents. This looks wonderful. You need to know that it’s very expensive to calculate shadow shape in real time particularly if the layer contains multiple sublayers with alpha-masked backing images. How can we keep our layer shadows and still have good performance?
So, if you know what the shape of your shadow needs to be, you can improve performance by specifying a shadowPath property. The default value of this property is nil, which causes the layer to use a standard shadow shape. If you specify a value for this property, the layer creates its shadow using the specified path instead of the layer’s composited alpha channel. So, we can use this property to determine the shape of shadow independently of the layer’s shape.
And what about programming code? All you need is to set up shadowPath property.
Also for triangle shape.
To sum up, Core Animation makes easy to generate dynamic shadows and attach them to any shape. You need to set up them correctly, and that’s all. Don’t forget about performance 🐶. If you know what the shape of your shadow needs to be, you can use shadowPath property to determine the shape of shadow independently of the layer’s shape.
Thanks for reading! I hope this writing was useful for you. Please don’t forget to 💚 if you found this article useful.
Source link https://blog.prototypr.io/what-should-you-know-about-shadows-691aa930ce02?source=rss—-eb297ea1161a—4