UIButton
iOS Development
Title Color
Swift
Programming Tips

How can I change UIButton title color?

Master System Design with Codemia

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

Introduction

The usual way to change a UIButton title color is setTitleColor(_:for:). That works well for classic UIKit buttons, but modern iOS buttons can also use configuration-based styling, which means the exact approach depends on how the button was created.

The Classic UIKit Solution

For a normal UIButton, call setTitleColor and specify the control state.

swift
1import UIKit
2
3let button = UIButton(type: .system)
4button.setTitle("Save", for: .normal)
5button.setTitleColor(.systemBlue, for: .normal)
6button.setTitleColor(.systemGray, for: .disabled)
7button.setTitleColor(.white, for: .highlighted)

The second argument matters because buttons can show different colors in different states such as:

  • '.normal'
  • '.highlighted'
  • '.disabled'
  • '.selected'

If you only set .normal, other states may still use defaults that look inconsistent later.

Setting the Color from Interface Builder Code

If the button comes from a storyboard or XIB, connect an outlet and style it in viewDidLoad.

swift
1import UIKit
2
3final class ViewController: UIViewController {
4    @IBOutlet private weak var saveButton: UIButton!
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        saveButton.setTitleColor(.systemGreen, for: .normal)
10        saveButton.setTitleColor(.systemGray, for: .disabled)
11    }
12}

This keeps the styling in one place and makes it obvious which states are intentionally customized.

When setTitleColor Seems Not to Work

On newer iOS versions, many buttons are created with UIButton.Configuration. In that case, direct title-color changes may appear to be ignored because the configuration is controlling foreground styling.

Use the configuration instead:

swift
1import UIKit
2
3var config = UIButton.Configuration.filled()
4config.title = "Continue"
5config.baseForegroundColor = .white
6config.baseBackgroundColor = .systemBlue
7
8let button = UIButton(configuration: config)

If you are using a configured button, this is usually the right direction. Mixing configuration styling and old-style appearance calls can produce confusing results.

State-Dependent Styling with configurationUpdateHandler

For configuration-based buttons, you can react to state changes in one place.

swift
1import UIKit
2
3var config = UIButton.Configuration.plain()
4config.title = "Retry"
5
6let button = UIButton(configuration: config)
7
8button.configurationUpdateHandler = { button in
9    var updated = button.configuration
10
11    if button.isEnabled {
12        updated?.baseForegroundColor = .systemRed
13    } else {
14        updated?.baseForegroundColor = .systemGray
15    }
16
17    button.configuration = updated
18}

This is cleaner than trying to mix stateful setTitleColor calls into a configuration-driven button lifecycle.

Use setAttributedTitle for More Complex Text Styling

If you need more than just one solid color, use an attributed title.

swift
1import UIKit
2
3let button = UIButton(type: .system)
4
5let attributes: [NSAttributedString.Key: Any] = [
6    .foregroundColor: UIColor.systemPurple,
7    .font: UIFont.boldSystemFont(ofSize: 18)
8]
9
10let title = NSAttributedString(string: "Delete", attributes: attributes)
11button.setAttributedTitle(title, for: .normal)

This is useful when color is only one part of a richer title style.

Be Careful with .tintColor

For system buttons, .tintColor can influence the title appearance, but it is not always the clearest or most precise way to control button text color.

swift
button.tintColor = .systemOrange

If your goal is explicitly "change the title color," prefer setTitleColor or configuration foreground styling. tintColor affects a broader set of UI behaviors and can be less predictable when the button style evolves.

Common Pitfalls

The most common mistake is setting the color only for .normal and then being surprised when the button looks different while highlighted or disabled. Another is calling setTitleColor on a configuration-based button and expecting it to override the configuration automatically. Developers also sometimes use tintColor when what they really want is direct control of title text color, which makes later styling harder to reason about.

Summary

  • Use setTitleColor(_:for:) for classic UIButton styling.
  • Set colors for the states the button will actually use.
  • If the button uses UIButton.Configuration, style the foreground through the configuration instead.
  • Use configurationUpdateHandler for state-dependent configuration styling.
  • Use attributed titles when color changes are part of richer text formatting.

Course illustration
Course illustration

All Rights Reserved.