Custom glass sidebar on iPad Workaround
As there is currently no Sidebar-like sheet on iPad, I'm using a NavigationStack in a View with .glassEffect
applied:
Discussion: https://developer.apple.com/forums/thread/793627
This came with two issues that needed workarounds:
FB19252414: Container glass background disappears when a Menu with a glass effect appears
When .glassEffect() is used to build a custom sideways sheet-like presentation on iPad, the glass background disappears when a Menu with a glass effect appears.
(this can be worked around by putting the glass in .background
using Color.clear.glassEffect()
)
Toolbar buttons in the bottom toolbar align with the device safe area instead of the NavigationStack container / are shown without padding inside the container:
(this can be worked around by avoiding the toolbar and using a .safeAreaBar + custom standalone glass buttons)
Example code:
// » SwiftUI Garden
// » https://swiftui-garden.com/Misc/iOS-26/Custom-glass-sidebar-on-iPad-Workaround
import MapKit
import SwiftUI
struct CustomGlassSidebarExample: View {
var body: some View {
Map()
.overlay(alignment: .leading) {
NavigationStack {
CustomGlassSidebarExampleScrollView()
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Menu(
content: {
Button("Example") {}
},
label: {
Image(systemName: "ellipsis")
}
)
}
}
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Button("Example", systemImage: "square.dashed") {}
Spacer()
Button("Example", systemImage: "square.dashed") {}
}
}
.navigationTitle("Example")
.navigationBarTitleDisplayMode(.inline)
.containerBackground(Color.clear, for: .navigation)
}
.frame(width: 400)
.frame(maxHeight: .infinity)
// .background + Color.clear is a workaround for glass disappearing when a Menu opens (last tested on Beta 8)
.background {
Color.clear
.glassEffect(in: .rect(cornerRadius: 36))
}
.clipShape(.rect(cornerRadius: 36))
.padding([.horizontal, .top])
}
}
}
struct CustomGlassSidebarExampleScrollView: View {
var body: some View {
ScrollView {
VStack {
ForEach(1 ... 30, id: \.self) { i in
NavigationLink(
destination: {
CustomGlassSidebarExampleScrollView()
},
label: {
RoundedRectangle(cornerRadius: 12)
.fill(.background)
.frame(maxWidth: .infinity)
.frame(height: 100)
.overlay {
Text("\(i)")
}
}
)
}
}
.padding()
}
.navigationTitle("Glass Sidebar Example")
.navigationBarTitleDisplayMode(.inline)
.containerBackground(Color.clear, for: .navigation)
}
}
#Preview {
CustomGlassSidebarExample()
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89