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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WYqycDFsynHH9VnnK7LNSf
This commit is contained in:
2026-09-19 17:31:46 +02:00
co-authored by Claude Sonnet 5
parent f454b4594a
commit e6136a3f63
+48 -4
View File
@@ -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
}