Reputation: 1379
Is it possible to make the navigation title of SwiftUI editable?
Unfortunately the navigationTitle
modifier only accepts Text
views and not TextField
views.
I want to do this instead of just using a text field below the navigation bar because I still want the nice default behaviour of having the modified title appear in the navigation bar inline when the user scrolls down and the navigation bar allocates space for the navigation title whether you define one or not.
Upvotes: 5
Views: 2535
Reputation: 10502
The navigationTitle
modifier now accepts a Binding<String>
argument, as well as the more usual String
-based initializer.
When using a bound value and the navigation bar is in its inline form, the title gains a drop-down menu with a Rename option. Tapping this allows the user to edit the view's title:
struct EditableTitleView: View {
@State private var title = "View Title"
var body: some View {
Text("Editable Title View")
.navigationTitle($title)
.navigationBarTitleDisplayMode(.inline)
}
}
This isn't exactly the same UX as always using a text field, but as it's a standard SwiftUI implementation it's a lot easier to implement.
You can place a custom view in your NavigationView at the position where the title might be expected to go by specifying a ToolbarItem
with a placement value of .principal
, for example in the code below. I've added the RoundedBorderTextFieldStyle
to make the text field more visible:
struct EditableTitleView: View {
@State private var editableTitle: String = "My Title"
var body: some View {
NavigationView {
Text("View with editable title")
.toolbar {
ToolbarItem(placement: .principal) {
TextField("Title", text: $editableTitle)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
}
}
}
Note that if you also add a navigationTitle
modifier into your view, its default large style on iOS will still display beneath the toolbar, but if it scrolls off the page it while disappear while your principal item will remain on screen. If you set .navigationBarTitleDisplayMode(.inline)
then the larger style title will never display.
I mention this because you should consider keeping a title for your view anyway, for a couple of reasons:
NavigationLink
pushes a view on the stack, you want a meaningful name to appear in the back button and the list of stacked views that appear on long press.Upvotes: 7
Reputation: 567
Try a TextField inside of a ToolbarItem in the principal slot of the toolbar. Create a computed property for the destination and give it an editable navigation title, too.
struct TextFieldNavigationTitleView: View {
@State var mainTitle = "Main Menu"
@State var areaOneTitle = "Area One"
var body: some View {
NavigationView {
NavigationLink("App Area One", destination: areaOne)
.toolbar {
ToolbarItem(placement: .principal) {
TextField("Navigation Title", text: $mainTitle)
}
}
}
}
var areaOne : some View {
Text("AREA ONE")
.toolbar {
ToolbarItem(placement: .principal) {
TextField("Area One Title", text: $areaOneTitle)
}
}
}
}
Upvotes: 2