Reputation: 7636
I use a NavigationLink
to navigate from "View1" to "View2", on the second view, the back button gets the title of the previous view
But, if the title of the previous view is very long, then the back button gets the text "Back"
How could I change that "Back" text?
I wanna make my app available in multiple languages, but it seems that "Back" does not change when phone's language changes
struct ContentView: View {
var body: some View {
return NavigationView {
VStack {
Text("View1")
NavigationLink(destination: Text("View2").navigationBarTitle("Title View2", displayMode: .inline)) {
Text("NavigationLink")
}
}.navigationBarTitle("Title View1")
}
}
}
PS: I'd like to keep this functionality as it it, I just want to change the language used for back button
Upvotes: 20
Views: 38790
Reputation: 279
Tested this on Xcode 15.3 and iOS 17.0
Just add a toolbar leading button with clear color and it should force show Back
as title for navbar.
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(navigationTitle)
.toolbar {
// Hack: To show back title for navigation bar
ToolbarItem(placement: .topBarLeading) {
Button { } label: {
Color.clear
}
}
}
Upvotes: 0
Reputation: 91681
I wouldn't hide the native back button as that would disable things like the back to swipe gesture, or tap-and-hold to select a page.
A better alternative is hiding the back button text, and then adding a custom button, in the child screen:
.toolbar {
ToolbarItem(placement: .principal) { Color.clear }
ToolbarItem(placement: .topBarLeading) {
Button("Back 2") { dismiss() }.offset(x: -25)
}
}
However, if the user tries to tap-and-hold on the new button they won't be able to select a page. Additionally, the -25
is not ideal. Therefore you might be better off with a solution that changes the previous screen's text.
In case you're wondering, it doesn't appear that the ToolbarItem
APIs (on the child page) can replace the back button icon/text. Even if you add every single placement, you'll notice that the original back button is intact:
.toolbar {
// `Group` used due to 10 limit on views
// leading
Group {
ToolbarItem(placement: .topBarLeading) { Text("L") }
ToolbarItem(placement: .cancellationAction) { Text("X") }
}
// center
Group {
ToolbarItem(placement: .principal) { Text("P") }
}
// trailing
Group {
ToolbarItem(placement: .automatic) { Text("A") }
ToolbarItem(placement: .navigation) { Text("N") }
ToolbarItem(placement: .primaryAction) { Text("1") }
ToolbarItem(placement: .confirmationAction) { Text("C") } // shows in bold
ToolbarItem(placement: .destructiveAction) { Text("D") }
ToolbarItem(placement: .topBarTrailing) { Text("T") }
}
// trailing but shows "ellipsis.circle" instead
Group {
ToolbarItem(placement: .secondaryAction) { Text("2") }
ToolbarItem(placement: .status) { Text("S") }
}
// doesn't appear on the top
Group {
ToolbarItem(placement: .keyboard) { Text("K") }
ToolbarItem(placement: .bottomBar) { Text("B") }
}
}
Upvotes: 3
Reputation: 1586
I found a solution which can work also very good.
View1 set a toolbar item with .principal and add your Text or what you want.
for example :
ToolbarItem(placement: .principal) {
HStack{
Text("View1")
}.font(.subheadline)
}
and set also your title in View1:
.navigationTitle("Back")
And do nothing in your view2. it will automatically add your view1 title to your view2 default back button text
Upvotes: 6
Reputation: 875
Add localization to your project. If language was set with user device settings(or simulator), after you add localization to your project it will work. Project's supported language must match with selected one on device.
Upvotes: -1
Reputation: 196
Create your own button, then assign it using .navigationBarItems(). I found the following format most nearly approximated the default back button.
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var backButton : some View {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack(spacing: 0) {
Image(systemName: "chevron.left")
.font(.title2)
Text("Cancel")
}
}
}
Make sure you use .navigationBarBackButtonHidden(true)
to hide the default button and replace it with your own!
List(series, id:\.self, selection: $selection) { series in
Text(series.SeriesLabel)
}
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: backButton)
Upvotes: 1
Reputation: 1225
You can create a custom back button in your navigation link by hiding native navigationBackButton. In the custom back button, you can add your translated custom back button title.
struct ContentView: View {
var body: some View {
return NavigationView {
VStack {
Text("View1")
NavigationLink("NavigationLink", destination: NextView())
}.navigationBarTitle("Title View1")
}
}
}
struct NextView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var backButton : some View { Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image("backImage") // BackButton Image
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
Text("Go Back") //translated Back button title
}
}
}
var body: some View {
VStack {
Text("View2")
}
.navigationBarTitle("Title View2",displayMode: .inline)
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: backButton)
}
}
Output:-
Upvotes: 7
Reputation: 953
I've managed to localize back buttons by providing translations for the Back
key in the Localizable.strings
file.
I am using SwiftUI though.
Upvotes: 7
Reputation: 14397
here is a workaround ....
struct ContentView: View {
@State private var isActive: Bool = false
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: DetailView(), isActive: $isActive) {
Text("Title View2")
}
}.navigationBarTitle(! isActive ? "Title View2" : "Your desired back Title", displayMode: .inline)
}
}
}
struct DetailView: View {
var body: some View {
Text("View2")
}
}
Upvotes: 9