iOS
PNG
Button Color
Image Manipulation
SwiftUI

Change color of png in buttons - ios

Master System Design with Codemia

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

Introduction

On iOS, the usual way to change the color of a PNG icon in a button is to treat the image as a template and apply a tint color. This works well for monochrome icons with transparency, while multicolor images require an actual redraw or separate prepared assets.

Use Template Rendering in UIKit

If the image is a single-color icon, convert it to template rendering mode first. Then the button’s tint color controls the visible color.

swift
1import UIKit
2
3final class ViewController: UIViewController {
4    private let button = UIButton(type: .system)
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        let icon = UIImage(named: "heart")?.withRenderingMode(.alwaysTemplate)
10        button.setImage(icon, for: .normal)
11        button.tintColor = .systemRed
12
13        view.addSubview(button)
14        button.center = view.center
15    }
16}

If you skip .alwaysTemplate, changing tintColor often appears to do nothing because the image is still rendered in its original mode.

Why Template Rendering Works

Template rendering ignores the original visible color information and uses only the image’s alpha mask. Every opaque pixel is drawn with the current tint.

That makes it ideal for icons, symbols, and other silhouette-style assets.

It is not a good fit for photos or richly colored artwork, because the original colors are flattened into one tint.

Different Colors for Different Button States

You may want the icon color to change when the button is highlighted or disabled.

A straightforward approach is to generate tinted variants.

swift
1import UIKit
2
3extension UIImage {
4    func tinted(with color: UIColor) -> UIImage {
5        let image = withRenderingMode(.alwaysTemplate)
6        let renderer = UIGraphicsImageRenderer(size: size)
7        return renderer.image { _ in
8            color.set()
9            image.draw(in: CGRect(origin: .zero, size: size))
10        }
11    }
12}
13
14let base = UIImage(named: "heart")!
15button.setImage(base.tinted(with: .systemRed), for: .normal)
16button.setImage(base.tinted(with: .systemPink), for: .highlighted)
17button.setImage(base.tinted(with: .systemGray), for: .disabled)

This gives you full control over per-state appearance.

SwiftUI Version

Since the article tags include SwiftUI, here is the same idea there.

swift
1import SwiftUI
2
3struct ContentView: View {
4    var body: some View {
5        Button(action: {}) {
6            Image("heart")
7                .renderingMode(.template)
8                .foregroundColor(.red)
9        }
10    }
11}

Again, this works best for monochrome PNG assets.

What to Do with Multicolor PNG Files

If the PNG contains multiple colors and you want to preserve some of that structure, template tinting is the wrong tool. In that case, you usually have two better options:

  • export separate colored assets from design
  • redraw the image into a graphics context with custom blending and cache the result

For example, a redraw helper can work, but it is heavier than template tinting and should not run repeatedly in hot UI paths.

Asset Catalog Tips

In Xcode asset catalogs, you can also mark images to render as templates. That is often cleaner than forcing rendering mode in code every time the asset is loaded.

If the asset is always meant to behave like a tintable icon, configuring it once in the asset catalog helps keep the UI code simpler.

Common Pitfalls

A common mistake is setting tintColor on the button while the image is still in original rendering mode.

Another pitfall is trying to tint a multicolor PNG and expecting all visual detail to survive. Template mode collapses the image into one tint.

Developers also sometimes generate tinted images repeatedly during scrolling, which creates unnecessary rendering work. Precompute or cache those variants.

Finally, if you are designing new iconography for iOS, consider whether SF Symbols or vector assets would fit the use case better than manually colored PNG files.

Summary

  • For monochrome PNG icons, use template rendering and a tint color.
  • In UIKit, apply .alwaysTemplate and then set tintColor.
  • In SwiftUI, use .renderingMode(.template) and foregroundColor.
  • Multicolor PNG files usually need separate assets or custom redraw logic.
  • Cache tinted variants if you generate them programmatically.

Course illustration
Course illustration

All Rights Reserved.