WWDC24 deal: 30% off our Swift and SwiftUI books! Learn more ...WWDC24 deal:30% off our Swift and SwiftUI books >>

Using foregroundColor(), foregroundStyle() or tint() to set text color in SwiftUI

SwiftUI has a few different modifiers that can change the color of text, such as foregroundColor(_:), foregroundStyle(_:), and tint(_:). They provide different functionality, but sometimes overlap and it can be hard to know for sure which modifier to choose. In this post we will go over some common use cases for all three of the modifiers and see which one suits best for what purpose.

Foreground color

foregroundColor(_:) modifier has been available in SwiftUI since iOS 13. It can be used to set a color for all stylable text in the hierarchy including text inside controls like buttons.

VStack {
    Text("Welcome!")
    
    Button("Log in") {
        // perform login
    }
}
.foregroundColor(.teal)
Screenshot showing the text Welcome and the button Log in colored in teal Screenshot showing the text Welcome and the button Login in colored in teal

There is also a version of foregroundColor(_:) that returns a Text rather than some View when applied directly to a Text view. This version can be used to set a color for specific words inside a sentence.

Text("The event is on \(Text("Sunday").foregroundColor(.teal)).")
Screenshot showing the word Sunday inside the sentence colored in teal Screenshot showing the word Sunday inside the sentence colored in teal
Books by Natalia PanferovaBooks by Natalia Panferova
WWDC24: 30% off all books!
  • Swift Gems

    100+ tips to take your Swift code to the next level

  • Integrating SwiftUI into UIKit Apps

    A detailed guide on gradually adopting SwiftUI in UIKit projects

The offer is active until the 16th of June.

Foreground style

foregroundStyle(_:) modifier was introduced in iOS 15 and instead of simply accepting a Color type, it accepts a ShapeStyle.

Just like foregroundColor(_:), foregroundStyle(_:) can be used to change the color of all text and other foreground elements in the hierarchy, like images and shapes. But it also provides some more advanced behavior.

Firstly, we can color the text using a gradient, rather than a simple Color. For example, we can pass a LinearGradient to the foregroundStyle(_:) modifier, because LinearGradient conforms to ShapeStyle.

VStack {
    Image(systemName: "globe")
    Text("Hello, world!")
}
.foregroundStyle(
    LinearGradient(
        colors: [.teal, .indigo],
        startPoint: .top,
        endPoint: .bottom
    )
)
Screenshot showing the globe symbol and the text Hello World colored with a linear gradient Screenshot showing the globe symbol and the text Hello World colored with a linear gradient

In addition, we can provide a HierarchicalShapeStyle, such as primary, secondary, tertiary or quaternary to modify the current style. The current style is the style that was set higher up in the hierarchy or the default foreground style if you haven't set a custom one.

VStack {
    Image(systemName: "globe")
    Text("Hello, world!")
        .foregroundStyle(.secondary)
}
.foregroundStyle(
    LinearGradient(
        colors: [.teal, .indigo],
        startPoint: .top,
        endPoint: .bottom
    )
)

In our example the current style is the linear gradient. The image will be displayed with the default primary hierarchical style, while the text will get the secondary style, but both will keep the linear gradient.

Screenshot showing the globe symbol with a linear gradient using primary style and the text Hello World with a linear gradient using secondary style Screenshot showing the globe symbol with a linear gradient using primary style and the text Hello World with a linear gradient using secondary style

While foregroundColor(_:) modifier can also be used to set primary or secondary semantic colors, it doesn't support tertiary or quaternary styles. Also worth noting that primary and secondary colors used with foregroundColor(_:) don't combine with the current foreground color like hierarchical styles set with foregroundStyle(_:) do.

Another important difference between foregroundColor(_:) and foregroundStyle(_:) is that foregroundStyle(_:) always returns some View. It doesn't have a version that returns Text when applied directly to a Text view. This means that it can be more efficient to choose foregroundColor(_:) modifier when setting a color for a single Text, because it won't create a new view but will rather modify the Text.

Text("Hello, world!")
    .foregroundColor(.teal) // returns `Text`
    
Text("Hello, world!")
    .foregroundStyle(.teal) // returns `some View`

This also means that using foregroundColor(_:) is the only way to set a different color for words within a string.

// ✅ Sets teal color for "world"
Text("Hello, \(Text("world").foregroundColor(.teal))!")

// ❌ Build error "'appendInterpolation' is unavailable"
Text("Hello, \(Text("world").foregroundStyle(.teal))!")

Update: In iOS 17 we can interpolate text with foregroundStyle() modifier. See Interpolate text with custom foreground style in SwiftUI post for details.

Tint

tint(_:) modifier was introduced in iOS 15 together with foregroundStyle(_:), but its purpose is to override the accent color for the view rather than to set the color of all foreground elements. When we apply a tint on a view hierarchy, it only affects the text inside controls, like buttons and links, not plain Text views.

VStack {
    Text("Welcome!")
    
    Button("Log in") {
        // perform login
    }
}
.tint(.teal)
Screenshot showing the text Welcome using the default label color and the button Log in colored in teal Screenshot showing the text Welcome using the default label color and the button Log in colored in teal

tint(_:) modifier can also be used in iOS to change the color of links embedded inside Text, as links are considered controls.

Text("Visit our [website](https://example.com).")
    .tint(.teal)
Screenshot showing the link embedded inside text colored in teal Screenshot showing the link embedded inside text colored in teal

Note that in macOS links have a special link color that cannot be changed with the tint(_:) modifier.