.navigationTitle disappears when using .toolbar and List inside NavigationStack (iOS 26 beta)
Summary
In iOS 26 beta, using .navigationTitle() inside a NavigationStack fails to render the title when combined with a .toolbar and a List. The title initially appears as expected after launch, but disappears after a second state transition triggered by a button press. This regression does not occur in iOS 18.
Steps to Reproduce
Use the SwiftUI code sample below (see viewmodel and Reload button for state transitions).
Run the app on an iOS 26 simulator (e.g., iPhone 16).
On launch, the view starts in .loading state (shows a ProgressView).
After 1 second, it transitions to .loaded and displays the title correctly.
Tap the Reload button — this sets the state back to .loading, then switches it to .loaded again after 1 second.
❌ After this second transition to .loaded, the navigation title disappears and does not return.
Actual Behavior
The navigation title displays correctly after the initial launch transition from .loading → .loaded.
However, after tapping the “Reload” button and transitioning .loading → .loaded a second time, the title no longer appears.
This suggests a SwiftUI rendering/layout invalidation issue during state-driven view diffing involving .toolbar and List.
Expected Behavior
The navigation title “Loaded Data” should appear and remain visible every time the view is in .loaded state.
✅ GitHub Gist including Screen Recording
👉 View Gist with full details
Sample Code
import SwiftUI
struct ContentView: View {
private let vm = viewmodel()
var body: some View {
NavigationStack {
VStack {
switch vm.state {
case .loading:
ProgressView("Loading...")
case .loaded:
List {
ItemList()
}
Button("Reload") {
vm.state = .loading
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
vm.state = .loaded
}
}
.navigationTitle("Loaded Data")
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu {
Text("hello")
} label: {
Image(systemName: "gearshape.fill")
}
}
}
}
}
}
struct ItemList: View {
var body: some View {
Text("Item 1")
Text("Item 2")
Text("Item 3")
}
}
@MainActor
@Observable
class viewmodel {
enum State {
case loading
case loaded
}
var state: State = .loading
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.state = .loaded
}
}
}
2
1
310