swiftuitoolbaritemsnavigationsplitview

SwiftUI ToolbarItem button disappears after rotation in iOS17


I am currently experiencing issues with a ToolbarItem in a NavigationSplitView detail view.

The ToolbarItem button is disappearing after rotating from portrait to landscape and then back to portrait again on an iPad or iPhone Max. This is occurring with iOS 17. Wrapping the detail view in a NavigationStack does not fix the issue.

In the following code the edit button in the navigation bar of the detail view disappears after rotating to landscape then back to portrait.

For apps with several detail views how can I add navigationBar items to those views and not have them disappear?

struct ContentView: View {
    
    @State private var preferredColumn =
        NavigationSplitViewColumn.detail

    var body: some View {
        NavigationSplitView(preferredCompactColumn: $preferredColumn) {
            Color.yellow
        } detail: {
            Color.blue
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: {
                            print("Button Pressed")
                        }, label: {
                            Text("Edit")
                        })
                    }
                }
        }
    }
}

Solution

  • So far this is my solution which works but is a hack until I can find a proper solution:

    struct ContentView: View {
        
        @State private var preferredColumn =
            NavigationSplitViewColumn.detail
        
        @State var refreshID = UUID()
        
        @Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
        @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
    
        var body: some View {
            NavigationSplitView(preferredCompactColumn: $preferredColumn) {
                Color.yellow
            } detail: {
                Color.blue
                    .onChange(of: verticalSizeClass, { oldValue, newValue in
                        refreshID = UUID()
                    })
                    .onChange(of: horizontalSizeClass, { oldValue, newValue in
                        refreshID = UUID()
                    })
                    .toolbar {
                        ToolbarItem(placement: ToolbarItemPlacement.primaryAction) {
                            Button(action: {
                                print("Button Pressed")
                            }, label: {
                                Text("Edit")
                                    
                            })
                            .id(refreshID)
                        }
                    }
            }
        }
    }