From e6136a3f6330b3034e997c693a1ef82efc104d00 Mon Sep 17 00:00:00 2001 From: Christophe Vila Date: Sat, 19 Sep 2026 17:31:46 +0200 Subject: [PATCH] fix: use sheet-presented group filter on iOS instead of NavigationSplitView Confirmed by hands-on testing: NavigationSplitView's compact-width collapse only pushes into the detail column when the sidebar drives navigation via row selection. GroupFilterView is a multi-select filter, not a picker, so on iPhone it showed only the sidebar with no way to reach the entry list at all -- exactly the risk the final whole-branch review flagged as unverified. iOS now uses a plain NavigationStack with EntryListView as the root and GroupFilterView presented as a sheet via the hamburger button. macOS keeps the persistent NavigationSplitView sidebar, which does work correctly at regular width. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf --- MyPass/ContentView.swift | 52 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/MyPass/ContentView.swift b/MyPass/ContentView.swift index 9334184..9c61a87 100644 --- a/MyPass/ContentView.swift +++ b/MyPass/ContentView.swift @@ -45,7 +45,11 @@ struct ContentView: View { private struct VaultRootView: View { @StateObject private var vaultVM: VaultViewModel @StateObject private var filterVM: GroupFilterViewModel + #if os(macOS) @State private var columnVisibility: NavigationSplitViewVisibility = .all + #else + @State private var showFilterSheet = false + #endif init(session: VaultSession) { _vaultVM = StateObject(wrappedValue: VaultViewModel(session: session)) @@ -53,6 +57,19 @@ private struct VaultRootView: View { } var body: some View { + content + .onChange(of: filterVM.selectedGroupIds) { _, newValue in + vaultVM.selectedGroupIds = newValue + } + .onChange(of: filterVM.lastToggledGroupId) { _, newValue in + vaultVM.lastToggledGroupId = newValue + } + } + + #if os(macOS) + // macOS has room for a persistent sidebar; NavigationSplitView's columnVisibility + // toggle works correctly at regular width. + private var content: some View { NavigationSplitView(columnVisibility: $columnVisibility) { if let root = vaultVM.session.database?.root { GroupFilterView(vm: filterVM, rootGroup: root) @@ -71,11 +88,38 @@ private struct VaultRootView: View { } } } - .onChange(of: filterVM.selectedGroupIds) { _, newValue in - vaultVM.selectedGroupIds = newValue + } + #else + // NavigationSplitView's compact-width collapse only pushes to detail when the + // sidebar drives navigation via row selection. Our sidebar is a multi-select + // filter, not a picker, so on iPhone it would just show the sidebar forever with + // no way to reach the entry list. Use a plain stack with the entry list as the + // root, and present the group filter as a sheet instead. + private var content: some View { + NavigationStack { + EntryListView(vm: vaultVM) + .toolbar { + ToolbarItem(placement: .navigation) { + Button { + showFilterSheet = true + } label: { + Image(systemName: "line.3.horizontal") + } + } + } } - .onChange(of: filterVM.lastToggledGroupId) { _, newValue in - vaultVM.lastToggledGroupId = newValue + .sheet(isPresented: $showFilterSheet) { + NavigationStack { + if let root = vaultVM.session.database?.root { + GroupFilterView(vm: filterVM, rootGroup: root) + .toolbar { + ToolbarItem(placement: .confirmationAction) { + Button("Done") { showFilterSheet = false } + } + } + } + } } } + #endif }