Change the navigation bar color - uinavigationbar

I am learning swiftui and i write very simple list like this.
NavigationView {
List {
Toggle(isOn: $isFemale) {
Text("Voice: \(self.isFemale == true ? "Female":"Male")").font(.system(size: 17)).bold()
}.padding(4)
NavigationButton(destination: LanguagePage()) {
VStack(alignment: .leading) {
Text("Change Language").font(.system(size: 17)).bold().padding(4)
Text("English - English").font(.system(size: 17)).font(.system(.body)).padding(4)
}
}
.navigationBarTitle(Text("Settings"), displayMode: .large)}
How can I change navigation bar colour? Currently, it is translucent. How can I change to opaque?

Using XCode 11.0 beta 5 (11M382q), I got it working with following:
struct TableWithNavTitle: View {
var body: some View {
// For navigation bar background color
UINavigationBar.appearance().backgroundColor = .red
return NavigationView {
List(0..<5) { item in
NavigationLink("\(item)", destination: Text("\(item)"))
}.navigationBarTitle("Title")
}
}
}

You can use the Appearance APIs to change to navigation bar title and background colors
init() { // for navigation bar title color
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor.red]
// For navigation bar background color
UINavigationBar.appearance().backgroundColor = .green
}
NavigationView {
List {
Toggle(isOn: $isFemale) {
Text("Voice: \(self.isFemale == true ? "Female":"Male")").font(.system(size: 17)).bold()
}.padding(4)
NavigationLink(destination: LanguagePage()) {
VStack(alignment: .leading) {
Text("Change Language").font(.system(size: 17)).bold().padding(4)
Text("English - English").font(.system(size: 17)).font(.system(.body)).padding(4)
}
}
.navigationBarTitle(Text("Settings"), displayMode: .large)}

Related

SwiftUI - Navigation View title is overlapping list

I have a simple list with a navigation view, where the navigation view is overlapping the list while scrolling.
Here is the look I want.
Here is what I am getting with the overlap
Here is the code
struct MedicalDashboard: View {
let menuItemData = MenuItemList()
var body: some View {
NavigationView {
List(menuItemData.items, id: \.id) { item in
MenuItemRow(menuItem: item)
}
.listStyle(.insetGrouped)
.navigationTitle("Dashboard")
.navigationBarItems(trailing:
Button(action: {
// TODO: - Pop up a sheet for the settings page.
print("User icon pressed...")
}) {
Image(systemName: "person.crop.circle").imageScale(.large)
}
)
.padding(.top)
}
}
}
when I add padding(.top) the overlap stops but I get a different color background on the navigation
On Xcode 13.4, except a missing }, without the .padding(.top) and with a custom List everything works like a charm for me.
The problem might come from MenuItemList().
I have still updated your code by replacing .navigationBarItems and by adding the sheet for you:
struct MedicalDashboard: View {
#State private var showSheet = false
var body: some View {
NavigationView {
List { // Custom list
Text("Hello")
Text("Salut")
}
.listStyle(.insetGrouped)
.navigationTitle("Dashboard")
.toolbar() { // .navigationBarItems will be deprecated
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
showSheet.toggle()
print("User icon pressed.")
}, label: {
Image(systemName: "person.crop.circle")
})
.sheet(isPresented: $showSheet) { /* SettingsView() */ }
}
}
}
} // New
}
Edit your post and show us MenuItemList().
Try this:
Swift
struct MedicalDashboard: View {
init() {
if #available(iOS 15, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithOpaqueBackground()
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
}
...
}

How to set the color of a NavigationView symbol button

My currently have a NavigationView with an embedded ToolbarItemGroup containing buttons with SF Symbols. I'm attempting to change the Trash button's color to that of red.
var body: some View {
NavigationView {
Text("Hello, World!")
.navigationTitle("Today")
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
Button(action: {
print("Add button was tapped")
}) {
HStack {
Image(.add)
}
}
Button(action: {
print("Trash button was tapped")
}) {
HStack {
Image(.trash)
.foregroundColor(.red)
.accentColor(.red)
}
}
.foregroundColor(.red)
.accentColor(.red)
}
}
}
}
I can't seem to set the color of the Trash image symbol to red. Image(.trash) is no typo, I'm using this extension I wrote!
Thanks :)
You can add .accentColor(.red) to the NavigationView. Although it will change the color of all ToolBar Items. An example would be
NavigationView {
SomeViews
}
.accentColor(.red)
It did the trick, as shown here
An other way to work on NavigationView. Although it will change the color of all ToolBar Items, too.
struct ContentView: View {
init() {
UINavigationBar.appearance().tintColor = UIColor.magenta
}
// your code follows
}

Remove space NavigationTitle but not the back button

I want to remove the NavigationTitle Space without removing the back button.
I have already tried this:
.navigationBarItems(trailing:
NavigationLink(destination: Preferences(viewModel: viewModel).navigationBarHidden(true)) {
Image(systemName: "gear")
.font(.title2)
}
)
but that removes the back button as well.
Standard Back button cannot be shown without navigation bar, because it is navigation item, so part of navigation bar. I assume you just need transparent navigation bar.
Here is demo of possible solution (tested with Xcode 12.1 / iOS 14.1) / images are used for better visibility /
struct ContentView: View {
init() {
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
UINavigationBar.appearance().standardAppearance = navBarAppearance
}
var body: some View {
NavigationView {
ZStack {
Image("large_image")
NavigationLink(destination: Image("large_image")) {
Text("Go to details ->")
}
}
.navigationBarItems(trailing: Button(action: {}) {
Image(systemName: "gear")
.font(.title2)
}
)
.navigationBarTitle("", displayMode: .inline)
}.accentColor(.red)
}
}

iOS SwiftUI: Correctly stack NavigationView with ScrollView and ZStack?

So I've been playing around with SwiftUI and I can't seem to stack NavigationView correctly with ScrollView and ZStack.
I'm trying to achieve a view with a .black background. Code below:
MainView.swift
var body: some View {
NavigationView {
ChildView()
}
}
ChildView.swift
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
ScrollView {
...
}
}
}
The above code gives me a black background but breaks the navigation bar behaviour.
How it looks:
How it should look:
So it seems like the the navigation doesn't go from the scrollEdgeAppearance to standardAppearance when scrolling.
Any ideas?
Put the ScrollView up as far as possible, otherwise the header animation will not work. The following code does what you want:
struct ChildView: View {
var body: some View {
ScrollView {
VStack(spacing: 20) {
ForEach(0..<40) { _ in
Text("Hello, World!")
.frame(maxWidth: .infinity)
}
}
.background(Color.green.edgesIgnoringSafeArea(.all))
}
.navigationBarTitle("Discover")
}
}
struct ContentView: View {
var body: some View {
NavigationView {
ChildView()
}
}
}
To achieve a completely black background, even if you scroll up the bottom, you have to fiddle around in UINavigationController. While there, I also changed the navigation bar colors to achieve your look and feel. Note that this doesn't keep track of whether the user enabled dark mode or not.
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
overrideUserInterfaceStyle = .dark
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = UIColor.black
appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance
navigationBar.scrollEdgeAppearance = appearance
}
}

How can I change the background color of the navigation bar in SwiftUI?

I would like to change the background color of the navigation bar. But what am I doing wrong that the colors look so different?
My code:
UINavigationBar.appearance().backgroundColor = .red
return VStack(spacing: 0) {
Text("Test")
.padding(.top, 9.5)
.padding(.bottom, 8)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color.red)
.font(.footnote)
NavigationView {
Text("Hello")
.navigationBarTitle(Text("Hi"), displayMode: .inline)
}
}
EDIT:
With this solution, it gets better but there is still a difference in color.
My code now:
struct ContentView: View {
var body: some View {
VStack(spacing: 0) {
Text("Test")
.padding(.top, 9.5)
.padding(.bottom, 8)
.frame(minWidth: 0, maxWidth: .infinity)
.background(Color("red")) // Now I use a color set
.font(.footnote)
NavigationView {
Text("Hello")
.navigationBarTitle(Text("Hi"), displayMode: .inline)
.background(NavigationConfigurator { nc in
nc.navigationBar.barTintColor = UIColor(named: "red") // Now I use a color set
})
}
}
}
}
struct NavigationConfigurator: UIViewControllerRepresentable {
var configure: (UINavigationController) -> Void = { _ in }
func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
UIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
if let nc = uiViewController.navigationController {
self.configure(nc)
}
}
}
iOS 16
You can set any color directly on toolbar items like the navigation bar with the following modifier:
.toolbarBackground(.red, in: .navigationBar)
iOS 15 and below
The issue is with the UINavigationBar's backgroundImage. You should set it to an empty UIImage like:
struct ContentView: View {
init() {
UINavigationBar.appearance().backgroundColor = .red // Or any other color
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}
var body: some View {
,,,
}
}
When you specify the displayMode: .inline parameter, the color underneath the navigation bar (in this case, white) gets blended into the nav bar's color, leaving you with this pinkish color. You will get full red if its a large title style.
This answer is a better way of setting the navigation bar color, and will work even with the .inline style.
Finally, note that Color.red is actually the same as UIColor.systemRed. If you use UIColor.red, you'll notice a difference in Dark Mode.

Resources