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)
}
}
Related
How can i change color of unselected icon (on screenshot) in TabView (SwiftUI)? Because this icon is invisible
You can use TabBarAccessor from my solution to Programmatically detect Tab Bar or TabView height in SwiftUI to change what you need as in below demo.
Tested with Xcode 11.4 / iOS 13.4
TabView {
Text("First View")
.background(TabBarAccessor { tabBar in
tabBar.unselectedItemTintColor = UIColor.red
})
.tabItem { Image(systemName: "1.circle") }
.tag(0)
Text("Second View")
.tabItem { Image(systemName: "2.circle") }
.tag(1)
}
Update: alternate via appearance also works
init() {
UITabBar.appearance().unselectedItemTintColor = UIColor.green
}
I’m trying to add an accessory view embedded in a navigation bar below the title, which can be seen in the default iOS calendar app (the “s m t w t f s” row) or the GitHub mobile app:
And I’d like it to work along with the large title style navigation bar like the GH mobile.
LazyVStack’s pinnedView with a section header almost work, but I can’t get the background color to make it seemless with the navigation bar, even with the ultraThinMaterial. It also leaves the divider line between the pinned view and the bar.
Is there a way to achieve this layout?
Solutions in SwiftUI, SwiftUI+Introspect, and UIKit are all welcome!
Have you tried setting a .safeAreaInset view? This will have the stickiness you're looking for, and items in the "main" part of the view will take its height into account when rendering, so won't get obscured.
Here's a quick example I knocked up:
struct ContentView: View {
var body: some View {
NavigationView {
List {
ForEach(0 ..< 30) { item in
Text("Hello, world!")
}
}
.navigationTitle("Accessory View")
.safeAreaInset(edge: .top) {
AccessoryView()
}
}
}
}
struct AccessoryView: View {
var body: some View {
HStack {
Button("Button") { }
Button("Button") { }
Button("Button") { }
Spacer()
}
.padding()
.background(Color(uiColor: .systemGroupedBackground))
.buttonStyle(.bordered)
.controlSize(.mini)
}
}
You have to give the view a background otherwise it'll be transparent – but that background will (as long as it's a colour or a material) automatically extend into the navigation bar itself. Here's a GIF of the above code in action, where I've set the background to match the grouped list's background:
It's not perfect, especially as it looks distinct from the nav bar on scroll, but it might be useable for you?
Another idea is to replace the navigation bar with a custom one like this:
{
...
}
.safeAreaInset(edge: .top) {
VStack(alignment: .leading, spacing: 8) {
HStack() {
Button {
presentationMode.wrappedValue.dismiss()
} label: {
Image(systemName: "chevron.backward")
}
Spacer()
Text(navigationTitle).font(.title2).bold()
.multilineTextAlignment(.center)
.foregroundColor(.accentColor)
.frame(maxWidth: .infinity)
Spacer()
}
HStack {
Button("Button") { }
Button("Button") { }
Button("Button") { }
Spacer()
}
}
.padding()
.background(
.bar
)
}
You will also have to set:
.navigationBarBackButtonHidden(true)
and do not set a navigation title:
// .navigationTitle("....")
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
}
Is it possible to make the navbar title clickable like a button?
Tried .navigationBarTitle(Button(....)), but this won’t work bc button doesn't conform to string protocol...
Here is a possible solution
struct ContentView: View {
var body: some View {
NavigationView {
GeometryReader { geo in
List {
Text("Have a nice day!")
Text("Today is sunny")
}.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarItems(leading: HStack{
Spacer().frame(width: geo.size.width * 0.5)
VStack{
Text("Title")
Button(action: {
print("I'm feeling lucky ;)")
})
{
Text("Button")
}
}
Spacer().frame(width: geo.size.width * 0.5)
})
}
}
}
}
You can not create a button on NavigationTitle in SwiftUI Navigation View
Solution: You have to create custom Navigation Bar & Other Views
In my SwiftUI app, I would like to bring the navigation bar items down like in Apple's own UIKit apps.
Seen below is a screenshot from the Health app. Notice how the profile picture is in line with the 'Summary' text. This is what I am looking to achieve.
I have tried using .padding(.top, 90) but this has not worked as it does not bring down the virtual box that allows the button to be clicked. Using padding means that you have to tap the button above the image/text.
Thank you.
Unfortunately I didn't find any solution for changing navigation bar height in iOS 13 with SwiftUI, and had the same issues earlier. Solution below will fit you, if your navigation bar is always only black and you're ok with gap on the top:
struct NavBarCustomItems: View {
init() {
setNavigationBarToBlackOnly()
}
func setNavigationBarToBlackOnly() {
let blackAppearance = UINavigationBarAppearance()
blackAppearance.configureWithOpaqueBackground()
blackAppearance.backgroundColor = .black
blackAppearance.shadowColor = .clear // to avoid border line
UINavigationBar.appearance().standardAppearance = blackAppearance
UINavigationBar.appearance().scrollEdgeAppearance = blackAppearance
}
var body: some View {
NavigationView {
VStack {
NavigationBarMimicry()
// here is your content
HStack {
Text("Favorites")
Spacer()
Button(action: {}) { Text("Edit") }
}
.padding()
Spacer()
VStack {
Text("Main screen")
}
// you need spacer(s) to be sure, that NavigationBarMimicry is always on the top
Spacer()
}
}
}
}
// MARK: here is what you need in navigation bar
struct NavigationBarMimicry: View {
var body: some View {
HStack {
Text("Summary")
.bold()
.font(.system(size: 40))
.foregroundColor(.white)
.padding(.horizontal)
Spacer()
Rectangle()
.foregroundColor(.white)
.frame(width: 40)
.padding(.horizontal)
}
.background(Color.black)
.frame(height: 40)
.navigationBarTitle("", displayMode: .inline)
// you can add it to hide navigation bar, navigation will work via NavigationLink
// .navigationBarHidden(true)
}
}
struct NavBarCustomItems_Previews: PreviewProvider {
static var previews: some View {
NavBarCustomItems().environment(\.colorScheme, .dark)
}
}
the result should be like this:
P.S. maybe the other ways are:
Put views in this order: VStack { NavigationBarMimicry(); NavigationView {...}};
uncomment line of code: .navigationBarHidden(true);