2

I want to change the TintColor of the NavigationBar.

In the following implementation, I want to change only "DetailView", but the color of the screen of "EditView" also changes.

How can I change only one screen?

struct TopView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView()) {
                    Text("Detail")
                }
            }
            .navigationBarTitle("Top")
        }
    }
}

struct DetailView: View {
    init(title: String) {
        UINavigationBar.appearance().tintColor = UIColor(named: "White")
    }

    var body: some View {
        VStack {
            NavigationLink(destination: EditView()) {
                Text("Edit")
            }
        }
        .navigationBarTitle("Detail", displayMode: .inline)
    }
}

struct EditView: View {
    @Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>

    var body: some View {
        VStack {
            Text("Title")
        }
        .navigationBarTitle("Edit", displayMode: .inline)
        .navigationBarItems(
            trailing:
            Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Save")
            }
        )
    }
}
Ika
  • 1,271
  • 1
  • 12
  • 20

1 Answers1

0

If I'm understanding the question aright then this might be a solution. It works by figuring out where we are in the navigation stack and then changing the accent color depending on the position. This changes the color of the navigation bar buttons. If you are relying on the accent color for other things, you'll need to override that, and I've illustrated that on the EditView. (I've left some logging so you can see how it works.)

enter image description here

enum ViewShowing : String {
      case top
      case detail
      case edit
}

class ViewShowingModel : ObservableObject {
      @Published var showing = ViewShowing.top
}

struct ContentView: View {

      @ObservedObject var viewModel = ViewShowingModel()

      var body: some View {

            return NavigationView {
                  VStack {
                        NavigationLink(destination: DetailView(title: "Detail", viewModel: viewModel)) {
                              Text("Go to: Detail")
                        }
                        Text("viewShowing: \(viewModel.showing.rawValue)")

                  }.onAppear(perform: {
                        print("top appear")
                        self.viewModel.showing = .top
                  })
                        .navigationBarTitle("Top").accentColorForView(viewModel.showing)
            }.accentColorForView(viewModel.showing)
      }
}


struct DetailView: View {

      var title : String
      @ObservedObject var viewModel : ViewShowingModel

      var body: some View {

            return VStack {
                  NavigationLink(destination: EditView(viewModel: viewModel)) {
                        Text("Go to Edit: \(title)")

                  }
                  Text("viewShowing: \(viewModel.showing.rawValue)")
                        .navigationBarTitle("\(title)", displayMode: .inline)
            }
            .onAppear(perform: {
                  print("detail appear")
                  self.viewModel.showing = .detail })
      }
}


struct EditView: View {
      @ObservedObject var viewModel : ViewShowingModel

      @Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
      var body: some View {
            VStack {
                  Text("Editing View")
                  Text("viewShowing: \(viewModel.showing.rawValue)")

                  Button(action: {
                        self.presentationMode.wrappedValue.dismiss()
                  }) {
                        Text("A Dismiss Button (no color override)")
                  }.padding()

                  Button(action: {
                        self.presentationMode.wrappedValue.dismiss()
                  }) {
                        Text("Another Dismiss Button (color override)").foregroundColor(Color(UIColor.systemBlue))
                  }.padding()

            }
            .navigationBarTitle("Edit", displayMode: .inline)
            .navigationBarItems(
                  trailing:
                  Button(action: {
                        self.presentationMode.wrappedValue.dismiss()
                  }) {
                        Text("Save")
                  }
            )
                  .onAppear(perform: {
                        print("edit appear")
                        self.viewModel.showing = .edit
                  })
      }
}

extension View {

      func accentColorForView(_ viewShowing : ViewShowing) -> some View {
            switch viewShowing {
            case .detail :
                  return accentColor(Color.red)
            case .top :
                  return accentColor(Color.purple)
            case .edit :
                  return accentColor(Color.green)
            }
      }
}

struct ContentView_Previews: PreviewProvider {
      static var previews: some View {
            ContentView()
      }
}
Obliquely
  • 7,002
  • 2
  • 32
  • 51