UIImageView
iOS development
image masking
Swift programming
Xcode

How can I mask a UIImageView?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Masking a UIImageView means controlling which parts of the image remain visible at runtime without permanently changing the source image file. In UIKit, the usual tools are rounded corners for simple shapes, layer.mask with CAShapeLayer for custom cutouts, and gradient masks for fade effects. The right method depends on whether you need a circle, a custom vector shape, or a soft transparency effect.

Simple circular or rounded masks

If the target shape is just a circle or rounded rectangle, you usually do not need a separate mask layer. The easiest approach is cornerRadius plus clipping.

swift
1import UIKit
2
3let imageView = UIImageView(image: UIImage(named: "avatar"))
4imageView.frame = CGRect(x: 40, y: 80, width: 120, height: 120)
5imageView.contentMode = .scaleAspectFill
6imageView.clipsToBounds = true
7imageView.layer.cornerRadius = imageView.bounds.width / 2

This works well for avatars, profile images, and card thumbnails. It is fast, readable, and built directly into the view-layer relationship.

Use a CAShapeLayer for custom shapes

When the visible area is not a simple rounded rectangle, assign a mask layer to imageView.layer.mask.

swift
1import UIKit
2
3let imageView = UIImageView(image: UIImage(named: "landscape"))
4imageView.frame = CGRect(x: 20, y: 80, width: 220, height: 140)
5imageView.contentMode = .scaleAspectFill
6
7let path = UIBezierPath()
8path.move(to: CGPoint(x: 0, y: 20))
9path.addLine(to: CGPoint(x: 110, y: 0))
10path.addLine(to: CGPoint(x: 220, y: 20))
11path.addLine(to: CGPoint(x: 220, y: 140))
12path.addLine(to: CGPoint(x: 0, y: 140))
13path.close()
14
15let maskLayer = CAShapeLayer()
16maskLayer.path = path.cgPath
17maskLayer.frame = imageView.bounds
18
19imageView.layer.mask = maskLayer

Opaque parts of the mask reveal the image. Transparent parts hide it. This is the usual solution for polygons, cutouts, and other custom vector shapes.

Use a gradient mask for fade effects

If you want the image to fade out instead of being sharply clipped, use a gradient layer as the mask.

swift
1import UIKit
2
3let imageView = UIImageView(image: UIImage(named: "header"))
4imageView.frame = CGRect(x: 0, y: 0, width: 320, height: 200)
5imageView.contentMode = .scaleAspectFill
6
7let gradient = CAGradientLayer()
8gradient.frame = imageView.bounds
9gradient.colors = [
10    UIColor.black.cgColor,
11    UIColor.clear.cgColor
12]
13gradient.startPoint = CGPoint(x: 0.5, y: 0.0)
14gradient.endPoint = CGPoint(x: 0.5, y: 1.0)
15
16imageView.layer.mask = gradient

This is a common UI pattern for hero images, overlays, and backgrounds that should blend into other content.

Layout timing matters

Masks depend on the image view's bounds. If you build the mask before Auto Layout finishes, the mask can be sized incorrectly.

For view-controller code, apply or update the mask after layout:

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3    maskLayer.frame = imageView.bounds
4}

That is especially important if the image view resizes on rotation or uses constraints rather than fixed frames.

Masking versus editing the image pixels

Masking in UIKit is a presentation effect. It changes what the view displays, not the underlying UIImage data. If you need an actually modified image file for export, upload, or reuse outside the view hierarchy, then you need image processing rather than a view-layer mask.

That distinction matters because many UI questions ask for masking when the real requirement is generating a new image asset.

Common Pitfalls

The most common mistake is setting the mask before the image view has its final bounds. The mask then looks misaligned or clipped incorrectly.

Another issue is using a full custom mask layer when cornerRadius would have solved the problem more simply. Do not overbuild the solution for a circle or rounded rectangle.

Developers also forget that layer.mask affects visibility, not the original pixel data. If the image needs to be exported in masked form, extra rendering work is required.

Finally, remember that a mask uses alpha semantics. The mask's visible and transparent areas determine what remains visible in the image view.

Summary

  • Use cornerRadius and clipping for circles and rounded rectangles.
  • Use CAShapeLayer with layer.mask for custom geometric masks.
  • Use CAGradientLayer as a mask for fade effects.
  • Apply or update masks after layout so the bounds are correct.
  • View masking changes presentation, not the original image data.

Course illustration
Course illustration

All Rights Reserved.