Starting from iOS and iPadOS 16 we have a new version of the navigationTitle(_:) modifier that accepts a binding to a string. We can use this modifier to let users rename items straight from the navigation title in the toolbar. This functionality could be useful in apps where an item is configurable, similar to a document in document-based apps.
In this post we will be looking at a simplified example of a note taking application, that displays a note list in the sidebar and a note editor in the detail view.
The initial code for the note detail view, where we see a text editor and the note name in the navigation bar, could be the following.
struct NoteView: View @ObservedObject var note: Note var body: some View TextEditor(text: $note.text) .padding() .navigationTitle(note.title)
We would like to let users rename notes from inside the detail view by typing a new name in the navigation bar title. In iOS 16 we can do that by passing a binding to a string instead of a plain string value to the
navigationTitle() modifier. It’s important to also set the navigation title display mode to
inline, otherwise the editing functionality won’t work. To be able to extract the binding from the title string, the
title property of the
Note object will need to be marked with
struct NoteView: View @ObservedObject var note: Note var body: some View TextEditor(text: $note.text) .padding() .navigationTitle($note.title) .navigationBarTitleDisplayMode(.inline) .toolbarRole(.editor) class Note: Identifiable, ObservableObject @Published var title: String @Published var text: String var id: UUID ...
By setting the toolbar role to
editor in iOS 16 we indicate that we would like users to edit the item in the detail view rather than just browse it. This places the navigation title on the leading edge of the bar leaving space for toolbar buttons in the middle. You can learn more about toolbars in iOS/iPadOS 16 from my previous article Customizable toolbar on iPad in SwiftUI.
When we pass a binding to the
navigationTitle() SwiftUI automatically changes the appearance of the title and adds an arrow indicator to show that there are actions available. Pressing on the arrow reveals the rename action that is also added automatically.
This functionality works on both iPhone and iPad, but the title is always centered in a compact size class, independent of the toolbar role setting.
To make sure that the name of the note updates in the sidebar when the user finishes editing it from the navigation title in the detail view, we should make the list row in the sidebar observe the
struct NoteListRow: View @ObservedObject var note: Note var body: some View NavigationLink(value: note.id) HStack Text(note.title) Spacer()
We already had to mark the
title of the
@Published to extract a binding for it to pass to the
navigationTitle() modifier. Now that the row view is observing the
Notethe view will get reevaluated when the
You can get the full sample for this post from our GitHub repo.
If you are enjoying our blog and would like to support us, you can now sponsor us on GitHub.
For updates about the blog and development tips, follow us on Twitter @nilcoalescing.