@@ -11,17 +11,20 @@ struct ViewShelf<ShelfContent: View, S: ShapeStyle>: ViewModifier {
1111 private let spacing : CGFloat ?
1212 private let backgroundFill : S
1313 private let includePadding : Bool
14+ private let isVisible : Bool
1415 private let shelfContent : ShelfContent
1516
1617 init (
1718 spacing: CGFloat ? = nil ,
1819 backgroundFill: S = . regularMaterial,
1920 includePadding: Bool = true ,
21+ isVisible: Bool = true ,
2022 @ViewBuilder shelfContent: ( ) -> ShelfContent
2123 ) {
2224 self . spacing = spacing
2325 self . backgroundFill = backgroundFill
2426 self . includePadding = includePadding
27+ self . isVisible = isVisible
2528 self . shelfContent = shelfContent ( )
2629 }
2730
@@ -33,15 +36,20 @@ struct ViewShelf<ShelfContent: View, S: ShapeStyle>: ViewModifier {
3336 GlassEffectContainer {
3437 content
3538 . safeAreaInset ( edge: . bottom) {
36- VStack ( spacing: spacing) {
37- shelfContent
39+ if isVisible {
40+ VStack ( spacing: spacing) {
41+ shelfContent
42+ }
43+ . horizontallyCentered ( )
44+ . if ( includePadding) {
45+ $0. padding ( )
46+ }
47+ . glassEffect ( in: RoundedRectangle ( cornerRadius: 34 ) )
48+ . padding ( . horizontal, 8 )
49+ . transition ( . move( edge: . bottom) )
50+ } else {
51+ EmptyView ( )
3852 }
39- . horizontallyCentered ( )
40- . if ( includePadding) {
41- $0. padding ( )
42- }
43- . glassEffect ( in: RoundedRectangle ( cornerRadius: 34 ) )
44- . padding ( . horizontal, 8 )
4553 }
4654 }
4755 } else {
@@ -53,17 +61,22 @@ struct ViewShelf<ShelfContent: View, S: ShapeStyle>: ViewModifier {
5361 func legacyLayout( for content: Content ) -> some View {
5462 content
5563 . safeAreaInset ( edge: . bottom) {
56- VStack ( spacing: spacing) {
57- shelfContent
58- }
59- . horizontallyCentered ( )
60- . if ( includePadding) {
61- $0. padding ( )
62- }
63- . background {
64- Rectangle ( )
65- . fill ( backgroundFill)
66- . edgesIgnoringSafeArea ( . bottom)
64+ if isVisible {
65+ VStack ( spacing: spacing) {
66+ shelfContent
67+ }
68+ . horizontallyCentered ( )
69+ . if ( includePadding) {
70+ $0. padding ( )
71+ }
72+ . background {
73+ Rectangle ( )
74+ . fill ( backgroundFill)
75+ . edgesIgnoringSafeArea ( . bottom)
76+ }
77+ . transition ( . move( edge: . bottom) )
78+ } else {
79+ EmptyView ( )
6780 }
6881 }
6982 }
@@ -75,13 +88,15 @@ public extension View {
7588 spacing: CGFloat ? = nil ,
7689 backgroundFill: S = . regularMaterial,
7790 includePadding: Bool = true ,
91+ isVisible: Bool = true ,
7892 @ViewBuilder _ shelfContent: @escaping ( ) -> ShelfContent
7993 ) -> some View {
8094 modifier (
8195 ViewShelf (
8296 spacing: spacing,
8397 backgroundFill: backgroundFill,
8498 includePadding: includePadding,
99+ isVisible: isVisible,
85100 shelfContent: shelfContent
86101 )
87102 )
@@ -90,6 +105,8 @@ public extension View {
90105
91106
92107#Preview {
108+ @Previewable @State var isVisible = true
109+
93110 NavigationView {
94111 List {
95112 Text ( " 1 " )
@@ -124,7 +141,19 @@ public extension View {
124141 Text ( " 0 " )
125142 }
126143 . navigationTitle ( " Preview " )
127- . shelf {
144+ . animation ( . default, value: isVisible)
145+ . toolbar {
146+ ToolbarItem ( placement: . primaryAction) {
147+ Button {
148+ withAnimation {
149+ isVisible. toggle ( )
150+ }
151+ } label: {
152+ Text ( " Toggle " )
153+ }
154+ }
155+ }
156+ . shelf ( isVisible: isVisible) {
128157 ProminentButton ( " Create " ) { }
129158 ProminentButton ( " Cancel " ) { }
130159 }
0 commit comments