Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change NavigationLink arrow color within Form

In SwiftUI, when a NavigationLink is placed inside of a Form, an arrow automatically appears on the trailing side of the NavigationLink. How can the color of this arrow be changed?

struct example: View {
    var body: some View {
        NavigationView {
            Form {
                NavigationLink(destination: Text("Example destination")) {
                    Text("Example link")
                }
            }
        }
    }
}
like image 685
Ryan Avatar asked Dec 18 '22 13:12

Ryan


2 Answers

Form/List is reusing UITableView and it's always been a problem to change the disclosure indicator tintColor *See: Question
So it comes to no surprise that .accentColor won't work here either.

The suggestions have mostly been to replace it with a custom view.
So lets do the same in SwiftUI.

Solution:

struct ContentView: View {
  var body: some View {
    NavigationView {
      Form {
        //Overlap NavigationLink and our Custom Cell arrangement
        ZStack {
          //Create a NavigationLink without the disclosure indicator
          NavigationLink(destination: Text("Hello, World!")) {
            EmptyView()
          }

          //Replicate the default cell
          HStack {
            Text("Custom UI")
            Spacer()
            Image(systemName: "chevron.right")
              .resizable()
              .aspectRatio(contentMode: .fit)
              .frame(width: 7)
              .foregroundColor(.red) //Apply color for arrow only
          }
          .foregroundColor(.purple) //Optional: Apply color on all inner elements
        }

        //Default style
        NavigationLink(destination: Text("Hello, World!")) {
          Text("Default UI")
        }
      }
    }
  }
}
  • NavigationLink with EmptyView gets rid of the default disclosure indicator
  • HStack is our Custom Cell View that replicates the default cell arrangement
    • Image(systemName: "chevron.right") is our replacement for the diclosure indicator
    • .foregroundColor will allow us to splash a color on either the entire HStack or just the Image (your choice)
  • ZStack allows to overlap the above two.
    • The NavigationLink basically makes the entire cell tappable

Result:

Result

like image 155
staticVoidMan Avatar answered Dec 24 '22 00:12

staticVoidMan


You can provide a custom view and hide the default NavigationLink arrow:

       NavigationLink(destination: Text("Hello, World!")) {}
       .opacity(0)
       .background(
         HStack {
            Text("Custom UI")
            Spacer()
            Image(systemName: "chevron.right")
              .resizable()
              .aspectRatio(contentMode: .fit)
              .frame(width: 7)
              .foregroundColor(.red) //Apply color for arrow only
          }
          .foregroundColor(.purple)
       ) 

Or specify the NavigationLink as background (so you have auto sizing):

         HStack {
            Text("Custom UI")
            Spacer()
            Image(systemName: "chevron.right")
              .resizable()
              .aspectRatio(contentMode: .fit)
              .frame(width: 7)
              .foregroundColor(.red) //Apply color for arrow only
          }
          .foregroundColor(.purple)
          .background(
             NavigationLink(destination: Text("Hello, World!")) {}
                .opacity(0)
          ) 
like image 20
Amir Khorsandi Avatar answered Dec 24 '22 02:12

Amir Khorsandi