Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I remove the sidebar toggle from a NavigationSplitView on iPad only in landscape mode

How do I remove the sidebar toggle from a NavigationSplitView on iPad in landscape mode but keep it in portrait mode? Similar to how it works in the home app in iOS 17.

I have this so far but it doesn't work correctly at first launch before switching orientation once:

struct SidebarMainView: View {
    @Environment(\.horizontalSizeClass) private var horizontalSizeClass
    @State private var isPortrait = true

    var body: some View {
        NavigationSplitView {
            List {
                Text("1")
                Text("2")
                Text("3")
            }
            .listStyle(SidebarListStyle()).toolbar(removing: isPortrait ? .none : .sidebarToggle).navigationTitle("HP").onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                guard let scene = UIApplication.shared.windows.first?.windowScene else { return }
                self.isPortrait = scene.interfaceOrientation.isPortrait
            }
        } detail: {
            Text("Select a department: \(self.isPortrait ? "yes" : "no")")
        }
    }
}

For reference, this is what the Home app looks like in different layouts. Note the forced and optional sidebar in each layout. I want to accomplish the same.

enter image description here enter image description here enter image description here enter image description here enter image description here

like image 457
Oskar Persson Avatar asked Nov 29 '25 17:11

Oskar Persson


1 Answers

For iOS 17+
We can use UIDevice.orientationDidChangeNotification to detect current orientation and toolbar(removing:) for removing sidebar toggle button.

struct ContentView: View {
    @State private var deviceOrientation = UIDevice.current.orientation

    var body: some View {
        NavigationSplitView {
            Text("sidebar")
                .detectOrientation($deviceOrientation)
                // After removing sidebar toggle, it was not adding when refreshing (Instead Visibility solves the problem)
                // .toolbar(removing:  isOrientationPortrait() ? .none : .sidebarToggle)
                .toolbar(isOrientationPortrait() ? .visible : .hidden, for: .navigationBar)
        } detail: {
            Text("Detail")
        }
    }

    private func isOrientationPortrait() -> Bool {
        return deviceOrientation == .portrait || deviceOrientation == .portraitUpsideDown
    }
}


extension View {
    func detectOrientation(_ orientation: Binding<UIDeviceOrientation>) -> some View {
        modifier(DetectOrientation(orientation: orientation))
    }
}

struct DetectOrientation: ViewModifier {
    
    @Binding var orientation: UIDeviceOrientation
    
    func body(content: Content) -> some View {
        content.onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in
                orientation = UIDevice.current.orientation
            }
    }
}

Hope It Helps !

like image 124
Nayan Dave Avatar answered Dec 01 '25 17:12

Nayan Dave



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!