Sometimes we need to create variants of our icons. This can be done by using template images and using a UIImageView with a tintColor change, however sometimes this isn't feasible. We can use our icons along with a mask to create new images of whatever color we want. In this episode we'll use UIGraphicsImageRenderer to quickly draw a new dimmed image for a highlighted button state.
Tinting an Image We will start by creating an extension on UIImage that will take a color and return a new UIImage. The source image will be used as a mask, using the alpha channel only to decide what pixels actually get drawn. We will use cgImage property and initialize a renderer using UIGraphicsImageRenderer. Next, we will create a context from renderer and map the mask into the specified bounds using clip. Next we will set the fill color and fill the context with the selected color. func tint(color: UIColor) -> UIImage { let maskImage = cgImage let bounds = CGRect(origin: .zero, size: size) let renderer = UIGraphicsImageRenderer(size: size) return renderer.image { context in let cgContext = context.cgContext cgContext.clip(to: bounds, mask: maskImage!) color.setFill() cgContext.fill(bounds) } } Using the Tint Image In PlayerViewController, we will replace our pauseImage with a dimmed purple color tintedImage for the highlighted button states. let tintedImage = pauseImage?.tint(color: Theme.Colors.purpleDimmed) playPauseButton.setImage(tintedImage, for: [.selected, .highlighted])