macosswiftuibackground-colornavigationviewnavigationlink

In a MacOS App using SwiftUI, how to modify the default blue background of a selected NavigationLink nested in a list?


Good day all. In a MacOS App using SwiftUI, how to modify the default blue background of a selected NavigationLink nested in a list? The list is inside a NavigationView. I could not find the solution here. What would be the code to add to the following basic exemple: Two TextView listed, and if we click on the TextView we display the correspondant View.

ContentView.swift:

import SwiftUI

struct ContentView: View {

  @State var selection: Int?

  var body: some View {

    HStack() {
      NavigationView {
        List () {
          NavigationLink(destination: FirstView(), tag: 0, selection: self.$selection) {
            Text("Click Me To Display The First View")
          } // End Navigation Link

          NavigationLink(destination: SecondView(), tag: 1, selection: self.$selection) {
            Text("Click Me To Display The Second View")
          } // End Navigation Link

        } // End list
        .frame(minWidth: 350, maxWidth: 350)
        .onAppear {
            self.selection = 0
        }

      } // End NavigationView
        .listStyle(SidebarListStyle())
        .frame(maxWidth: .infinity, maxHeight: .infinity)

    } // End HStack
  } // End some View
} // End ContentView

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

FirstView.swift:

import SwiftUI

struct FirstView: View {

  var body: some View {
    Text("(1) Hello, I am the first view")
      .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct FirstView_Previews: PreviewProvider {
  static var previews: some View {
    FirstView()
  }
}

SecondView.swift:

import SwiftUI

struct SecondView: View {
  var body: some View {
    Text("(2) Hello, I am the second View")
      .frame(maxWidth: .infinity, maxHeight: .infinity)
  }
}

struct SecondView_Previews: PreviewProvider {
  static var previews: some View {
    SecondView()
  }
}

Here is the result if we click on the first row... the background is blue when selected! How to change this default color? Thanks in advance for your help.

enter image description here


Solution

  • the following code is one option to achieve what you want:

    struct ContentView: View {
    
    @State var selection: Int? = 0
    @State var pressed: Int? = 0
    
    init() {
        UITableViewCell.appearance().selectionStyle = .none
        UITableView.appearance().backgroundColor = UIColor.clear
    }
    
    var body: some View {
    
        var theBinding = Binding(
            get: { self.selection },
            set: {
                self.selection = $0
                self.pressed = $0 == nil ? self.pressed : $0!
        })
    
        return HStack() {
            NavigationView {
                List {
                    NavigationLink(destination: FirstView(), tag: 0, selection: theBinding) {
                        Text("Click Me To Display The First View")
                    }.listRowBackground(self.pressed == 0 ? Color.red : Color.green)
    
                    NavigationLink(destination: SecondView(), tag: 1, selection: theBinding) {
                        Text("Click Me To Display The Second View")
                    }.listRowBackground(self.pressed == 1 ? Color.red : Color.green)
    
                }.frame(minWidth: 350, maxWidth: 350)
                    .onAppear { self.pressed = 0 }
    
            }.listStyle(SidebarListStyle())
             .frame(maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    }