11.9 C
New York
Monday, March 10, 2025

ios – Persist overlay view within the element aspect of NavigationSplitView


When you connect the PlayerBar to the NavigationSplitView utilizing .safeAreaInset(edge: .backside) then it stays on high of the nested NavigationStack. Nonetheless, it additionally stays on high of the sidebar when it’s expanded, which isn’t ultimate.

To work round the issue of the PlayerBar protecting the sidebar, a masks might be added to PlayerBar when the sidebar is displaying, to masks out the half that’s protecting the sidebar:

  • The presence of the sidebar might be detected by supplying the NavigationSplitView with a binding to the column visibility.

  • The width to be masked out ought to correspond to the width of the sidebar. This may be measured utilizing an .onGeometryChange modifier on the sidebar content material.

  • It seems to be finest if the masking change makes use of an animation that’s related in pace and magnificence to the native animation used for revealing the sidebar. Utilizing .spring(period: 0.3) works fairly effectively.

Within the up to date instance under, PlayerBar has been modified to a easy view, quite than a generic wrapper for another content material.

struct ContentView: View {
    let films = ["Movie 1", "Movie 2", "Movie 3"]
    @State personal var sidebarWidth = CGFloat.zero
    @State personal var columnVisibility = NavigationSplitViewVisibility.automated

    var physique: some View {
        NavigationSplitView(columnVisibility: $columnVisibility) {
            Textual content("Classes goes right here")
                .body(maxWidth: .infinity)
                .onGeometryChange(for: CGFloat.self) { proxy in
                    proxy.dimension.width
                } motion: { width in
                    sidebarWidth = width
                }
        } element: {
            NavigationStack {
                // ... content material as earlier than
            }
        }
        .safeAreaInset(edge: .backside) {
            PlayerBar()
                .masks {
                    Shade.black
                        .padding(.main, columnVisibility == .detailOnly ? 0 : sidebarWidth)
                        .animation(.spring(period: 0.3), worth: columnVisibility)
                }
        }
    }
}

struct PlayerBar: View {
    var physique: some View {
        Shade.blue
            .body(peak: 50)
            .clipShape(.rect(cornerRadius: 15))
            .padding()
    }
}

Animation

Ps. You referred to the Music app on iPad – it seems to be like that is utilizing one thing extra within the model of a TabView for the nested element, quite than a NavigationStack.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles