Layer is an abstraction of graphical content that manages the visual representation of interface elements in mobile applications. Unlike UIView, layer does not handle touch events and does not participate in Auto Layout — its sole purpose is rendering, animation, and pixel composition. According to Apple QuartzCore Documentation, 2025, every UIView in iOS has an associated CALayer that actually manages drawing and animation. Understanding the structure of layers allows a developer to control rendering performance at the level of individual pixels.
Key Takeaways
Layer is a low-level graphics system object that stores a bitmap image of a screen fragment and manages its visual attributes: position, size, rotation, opacity, shadow, and color. In iOS, every UIView has a built-in CALayer accessible via the layer property. A developer can work directly with the layer, bypassing UIView, for fine-grained rendering control.
The layer architecture follows the Model-View-Controller pattern, where CALayer acts as the Model — it stores the state of visual properties. Core Animation is the Controller that manages animation transitions between states. View (UIView) is an optional wrapper that adds touch handling and Auto Layout participation.
According to Apple WWDC 2024, the modern iOS rendering pipeline uses Metal for layer compositing. Each CALayer is rendered into a separate buffer, after which Core Animation composites all buffers into the final image, taking into account opacity and blending modes.
In Android, the analog of layers is View and background Drawable, but direct work with graphics layers is available through Canvas and RenderNode in Android 10+. Understanding the layer concept is important for optimizing rendering on both platforms.
The main difference lies in the area of responsibility. View handles user input (touches, gestures), positioning (Auto Layout, frame), and lifecycle. Layer is exclusively responsible for visual presentation: content rendering, property animation, and compositing with other layers.
This separation allows caching the bitmap representation of the layer independently of the View. If the layer does not change, Core Animation uses the cached frame without calling drawRect. For static elements, this provides a significant performance boost without code changes.
iOS provides a rich hierarchy of classes inheriting from CALayer. Each subclass is optimized for a specific scenario: text display, vector graphics, gradients, or 3D transformations. Choosing the right layer type directly affects rendering performance.
In Android, the layer concept is implemented through RenderNode, ViewLayer, and HardwareRenderer. Starting with Android 5.0 (API 21), each View is rendered into its own hardware acceleration layer, allowing animations without calling onDraw.
Additional flexibility in iOS is provided by CAReplicatorLayer and CAEmitterLayer. The first is used for creating repeating patterns, the second for particle systems. Both run exclusively on the GPU, enabling complex visual effects without performance loss.
Layer hierarchy in iOS follows a tree structure: each CALayer can contain multiple child sublayers. All transformations applied to the parent layer — scale, rotation, translation — are automatically applied to child elements. This ensures visual consistency during animations.
Scene composition is performed by Core Animation in the following order: first the background is rendered, then each child layer in order from bottom to top. For each layer, Core Animation checks opacity, mask, and blending mode properties, then composites them into the final frame.
According to Apple Documentation, compositing a layer with opaque = true and no alpha channel is done without additional passes — the GPU simply copies pixels over the previous layer. If the layer has transparency, the GPU performs alpha blending, which requires additional computational resources.
In Android, layer compositing is performed through SurfaceFlinger — a system service that receives buffers from each application and composites them according to z-order. Each Window in Android is a separate Surface that can contain multiple graphics layers.
CALayer.mask — a property that allows applying a mask of arbitrary shape to a layer. The mask can be any other CALayer — for example, CAShapeLayer with a circular path or CAGradientLayer for creating a smooth opacity transition. Using masks increases GPU load as it requires an additional rendering pass to compute alpha values for each pixel.
For simple rectangular clipping, it is recommended to use cornerRadius and masksToBounds. Unlike masks via the mask property, cornerRadius is handled by hardware at the rasterization stage and does not require an additional pass.
shouldRasterize is a key CALayer property for performance optimization. When shouldRasterize is set to true, Core Animation renders the layer and all its sublayers into a separate offscreen buffer. On subsequent frames, the cached bitmap image is used instead of re-rendering.
Caching is effective for static or rarely changing layers: shadows, gradients, text with rounded corners. However, for frequently updated layers (animation, video, scrolling), rasterization can degrade performance since each frame requires cache regeneration.
According to research by Objc.io, proper use of shouldRasterize on iPad Pro reduces rendering time of a complex screen from 25 ms to 8 ms — more than three times. The key condition is that the layer should not change more often than once every 3–5 frames.
The first example demonstrates setting basic visual properties of CALayer in Swift — corner radius, shadow, and border:
import UIKit
class StyledView: UIView {
override func awakeFromNib() {
super.awakeFromNib()
layer.cornerRadius = 12
layer.masksToBounds = false
layer.shadowColor = UIColor.darkGray.cgColor
layer.shadowOpacity = 0.3
layer.shadowOffset = CGSize(width: 0, height: 4)
layer.shadowRadius = 8
}
}
The second example — creating a layer animation in Swift using CABasicAnimation. The position property is animated without UIView involvement:
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = NSValue(cgPoint: CGPoint(x: 0, y: 0))
animation.toValue = NSValue(cgPoint: CGPoint(x: 150, y: 300))
animation.duration = 1.0
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
targetLayer.add(animation, forKey: "moveAnimation")
The third example — working with RenderNode in Kotlin on Android. RenderNode is a direct analog of CALayer, allowing operations with graphics layers at the Canvas level:
import android.graphics.renderer.RenderNode
fun createLayer(): RenderNode {
val node = RenderNode("customLayer")
node.setPosition(0, 0, 300, 200)
node.setScaleX(1.5f)
node.setScaleY(1.5f)
val canvas = node.beginRecording()
canvas.drawColor(android.graphics.Color.BLUE)
node.endRecording()
return node
}
Frequently Asked Questions
UIView is a wrapper around CALayer that adds touch handling and Auto Layout participation. Layer only handles rendering and animation. You can work with CALayer directly, but UIView is necessary for handling input events.
shouldRasterize enables caching the layer into a separate offscreen buffer. Use it for static or rarely changing elements with shadows or complex compositing. Do not use it for frequently animated layers — cache regeneration will be more expensive than direct rendering.
Set the cornerRadius property for rounding corners and masksToBounds = true for clipping content to the layer bounds. For shadows, masksToBounds must be false, otherwise the shadow will be clipped — in this case, use a separate layer for the shadow.
Yes, RenderNode in Android 10+ provides similar functionality: managing position, scale, rotation, and opacity at the graphics layer level. Canvas and HardwareRenderer provide GPU-based rendering. However, architecturally Android does not separate View and layer as strictly as iOS does.
A shadow in CALayer is computed via shadowPath or automatically based on the alpha channel. Automatic computation requires traversing all pixels of the layer, which is expensive. Specify an explicit shadowPath — a rectangle or UIBezierPath — this allows the GPU to compute the shadow without traversing the content.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also