Black Friday 2024 deal: 30% off our Swift and SwiftUI books! Learn more ...Black Friday 2024 deal:30% off our Swift and SwiftUI books >>

Editable navigation titles in SwiftUI on iOS 16

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.

Screenshot of a simple note taking app on iPad Screenshot of a simple note taking app on iPad

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)
    }
}
Integrating SwiftUI into UIKit Apps by Natalia Panferova book coverIntegrating SwiftUI into UIKit Apps by Natalia Panferova book cover

Black Friday 2024 offer: 30% off!$45$32

A detailed guide on gradually adopting SwiftUI in UIKit projects

Updated for iOS 18 and Xcode 16!

Integrating SwiftUI into UIKit Appsby Natalia Panferova

  • Upgrade your apps with new features like Swift Charts and Widgets
  • Support older iOS versions with effective backward-compatible strategies
  • Seamlessly bridge state and data between UIKit and SwiftUI using the latest APIs
Black Friday 2024 offer: 30% off!

A detailed guide on gradually adopting SwiftUI in UIKit projects

Integrating SwiftUI into UIKit Apps by Natalia Panferova book coverIntegrating SwiftUI into UIKit Apps by Natalia Panferova book cover

Integrating SwiftUI
into UIKit Apps

by Natalia Panferova

Updated for iOS 18 and Xcode 16!

$45$32

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 @Published.

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.

Screenshot of the sample notes app showing the rename action in the title menu Screenshot of the sample notes app showing the rename action in the title menu

This functionality works on both iPhone and iPad, but the title is always centered in compact size class, independent of the toolbar role setting.

Swift Gems by Natalia Panferova book coverSwift Gems by Natalia Panferova book cover

Black Friday 2024 offer: 30% off!$35$25

100+ tips to take your Swift code to the next level

Swift Gemsby Natalia Panferova

  • Advanced Swift techniques for experienced developers bypassing basic tutorials
  • Curated, actionable tips ready for immediate integration into any Swift project
  • Strategies to improve code quality, structure, and performance across all platforms
Black Friday 2024 offer: 30% off!

100+ tips to take your Swift code to the next level

Swift Gems by Natalia Panferova book coverSwift Gems by Natalia Panferova book cover

Swift Gems

by Natalia Panferova

$35$25

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 Note object.

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 Note with @Published to extract a binding for it to pass to the navigationTitle() modifier. Now that the row view is observing the Note, the view will get reevaluated when the title changes.

Screenshot of the sample notes app showing the updated title in the sidebar Screenshot of the sample notes app showing the updated title in the sidebar


You can get the full sample for this post from our GitHub repo.