42

When you click on the button it takes you to a new view and puts a back button in the top left. I can't figure out what property controls the color of the back button. I tried adding an accentColor and foregroundColor but they only edit the items inside the view.

var body: some View {
    NavigationView {
        NavigationLink(destination: ResetPasswordView()) {
            Text("Reset Password")
            .foregroundColor(Color(red: 0, green: 116 / 255, blue: 217 / 255))
            .padding()
        }
    }
}
turingtested
  • 6,356
  • 7
  • 32
  • 47
Michael St Clair
  • 5,937
  • 10
  • 49
  • 75

12 Answers12

108

You can use the accentColor property on the NavigationView to set the back button color, like in this example:

var body: some View {
    NavigationView {
        List(1..<13) { item in
            NavigationLink(destination: Text("\(item) x 8 = \(item*8)")) {
                Text(String(item))
            }
        }.navigationBarTitle("Table of 8")
    }.accentColor(.black) // <- note that it's added here and not on the List like navigationBarTitle()
}
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
turingtested
  • 6,356
  • 7
  • 32
  • 47
  • This is the best way to do it based on all answers here. It's the only way to do it the SwiftUI way, and without globally editing the SceneDelegate. – eResourcesInc Dec 19 '19 at 21:31
  • Very swiftui idiomatic, nice solution. – cgiacomi Apr 07 '20 at 12:08
  • Nice solution, but if you are using XCode 12, you might be interested in my answer. – Ella Gogo Jul 25 '21 at 08:49
  • 6
    `accentColor` is now marked soon-to-be deprecated with the suggestion of "Use the asset catalog's accent color or View.tint(_:) instead.". I've tried using `tint` but that only tint additional buttons I add via a `toolbar()` modifier. – FateNuller Apr 23 '22 at 04:05
  • 1
    I can't get it to work with `tint` either and can't use the asset catalog as I have many different styles for user themes. – Darren Aug 05 '22 at 08:54
12

I was trying to do the same for a while, and do not think there is SwiftUI solution yet. One of things that will get work done though (if it works for your use case) is UIKit's appearance:

UINavigationBar.appearance().tintColor = .black

Predrag Samardzic
  • 2,661
  • 15
  • 18
  • 7
    This solution is no longer working as of iOS 16. – cseh_17 Sep 20 '22 at 14:29
  • [UINavigation bar appearance tint does not work in iOS 16](https://stackoverflow.com/questions/73709390/uinavigation-bar-appearance-tint-does-not-work-in-ios-16) – Araxias Jan 05 '23 at 15:37
8

I doubt this is the right way to do it, but I got it to work by modifying the SceneDelegate.swift to set the window tint color.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    // Use a UIHostingController as window root view controller
    let window = UIWindow(frame: UIScreen.main.bounds)
    window.rootViewController = UIHostingController(rootView: ContentView())
    window.tintColor = .green // set the colour of the back navigation text
    self.window = window
    window.makeKeyAndVisible()
}
Ty.N
  • 83
  • 6
  • 1
    Ya that would work if I wanted to change all of them, but I only want to change it on a single screen where I have a different background color – Michael St Clair Jun 12 '19 at 02:11
8

Add .accentColor modifier to NavigationView like shown below

NavigationView {
    Text("Hello World")
      .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button("Close") { }
                    }
            }
 }
 .accentColor(.themeColor)
Pankaj Wadhwa
  • 3,073
  • 3
  • 28
  • 37
6

If you are using XCode 12, consider setting AccentColor in Assets.xcassets. XCode will use this color for all navigation back buttons in the app.

Note that this will also affect other UI elements. One of them is button. You can always overide this using accentColor modifier:

Button("Button With Different Accent Color") { 
   // do something useful
}
.accentColor(.red)
Ella Gogo
  • 1,051
  • 1
  • 11
  • 17
  • Perfect solution for changing the default color for all control components (including Back buttons). Note that `accentColor(…)` is soon to be deprecated and Apple now recommends `tint(…)` instead, which seems to work when applied directly to a control (as in this solution's example), but does not change the color of the Back button when applied to a NavigationView (which was OP's desire). I am not sure how Apple expects developers to apply exceptions to controls like the Back button in the future, but it's possible their goal here is to discourage it. – Nathan Hosselton Jul 01 '22 at 21:43
5

Asset Catalog Solution

Add AccentColor set in the Asset Catalog (Assets.xcassets). Xcode applies the color you specify in this color set as your app’s accent color.

Short Solution

After adding the Accent Color to your Asset Catalog, your Navigation Bar back buttons will turn to that color. That's all you need it.

More Details

If your app doesn’t have an AccentColor color set, create a color set manually via the steps listed below:

  1. In the Project navigator, select an asset catalog.
  2. Click the Add button (+) at the bottom of the outline view.
  3. In the pop-up menu, choose Color Set. A new color set appears in the outline view and opens in the detail area.
  4. Double-click the color set name in the outline view to rename the color set with a descriptive name, and press the Return key.
  5. In Build Settings, find the build setting for “Global Accent Color Name”. Double-click the build setting, type in the name of your accent color set, and press Return.

Access the accent color from your code

By default, your accent color applies to all views and controls in your app that use a tint color, unless you override the color for a specific subset of the view hierarchy. However, you might want to incorporate the accent color into other parts of your user interface that don’t rely on a tint color, like static text elements. To use the accent color value from an asset catalog in code, load the color like this:

SwiftUI

Text("Accent Color")
    .foregroundStyle(Color.accentColor)

UIKit

label.textColor = UIColor.tintColor

What is Accent Color?

An accent color, or tint color, is a broad theme color that applies to views and controls in your app. Use an accent color to quickly create a unifying color scheme for your app. You can set an accent for your app by specifying an accent color in your asset catalog.

accent color

for more information regarding the topic check the documentation.

MGY
  • 7,245
  • 5
  • 41
  • 74
4

Hello maybe it's to late, but based on previous answers I made view modifier which allows you to change color or add text. This approach will avoid you to write boilerplate code everywhere you need back button.

import Foundation
import SwiftUI

struct NavigationBackButton: ViewModifier {

    @Environment(\.presentationMode) var presentationMode
    var color: UIColor
    var text: String?

    func body(content: Content) -> some View {
        return content
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(
                leading: Button(action: {  presentationMode.wrappedValue.dismiss() }, label: {
                    HStack(spacing: 2) {
                        Image(systemName: "chevron.backward")
                            .foregroundColor(Color(color))

                        if let text = text {
                            Text(text)
                                .foregroundColor(Color(color))
                        }
                    }
                })
            )
    }
}

extension View {
    func navigationBackButton(color: UIColor, text: String? = nil) -> some View {
        modifier(NavigationBackButton(color: color, text: text))
    }
}

And usage is pretty straightforward just use this modifier on your destination view of navigation link.

Back Button with text:

.navigationBackButton(color: .white, text: "Back")

Back Button without text:

.navigationBackButton(color: .white)
Vadims Krutovs
  • 197
  • 2
  • 3
  • 1
    Rewrite system component should be avoided as much as possible. You're losing drag top-left-corner, the long press on the native back button – Florian Jan 25 '23 at 15:23
3

This worked for me:

let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]
Starls
  • 43
  • 4
0

In iOS 16 Apple added a new workaround, go to Assets.xcassets add new color set name "AccentColor" if not exist. And set it's values. iOS wil pick color for background button from here Sample Picture.

Asad Mehmood
  • 341
  • 2
  • 12
0

In iOS 16, .accentColor is marked as deprecated. Use .tint instead.

NavigationStack {
        List {
              NavigationLink("Action_1") {
                  Action_1_View()
              }
              NavigationLink("Action_2") {
                  Action_2_View()
              }
        }
  }
  .tint(.gray)
AechoLiu
  • 17,522
  • 9
  • 100
  • 118
-1

.navigationBarBackButtonHidden(true)
        .navigationBarItems(leading:
                Button(action: {presentation.wrappedValue.dismiss()}, label: {
                    HStack {
                    Image(systemName: "chevron.backward")
                        .foregroundColor(Color(UIColor.darkGray))
                    Text(username)
                        .foregroundColor(Color(UIColor.darkGray))
                        .font(UIHelper.largeSize())
                    }
                })
Behzad Moulodi
  • 147
  • 2
  • 11
-2

You could try setting the foregroundColor or the accentColor to the NavigationView (after your second to last closing bracket)

EmilioPelaez
  • 18,758
  • 6
  • 46
  • 50