@@ -88,6 +88,7 @@ private struct ToastHostModifier: ViewModifier {
8888 @Environment ( \. safeAreaInsets) private var safeAreaInsets
8989 @State private var tabBarHeight = CGFloat . zero
9090 private let toastPresenter = ToastPresenter . presenter
91+ private let placement = ToastPresentationPlacement . current
9192
9293 func body( content: Content ) -> some View {
9394 content
@@ -98,7 +99,7 @@ private struct ToastHostModifier: ViewModifier {
9899 . onChange ( of: toastPresenter. item? . id) { _, _ in
99100 updateTabBarHeight ( )
100101 }
101- . overlay ( alignment: . bottom ) {
102+ . overlay ( alignment: placement . alignment ) {
102103 if let item = toastPresenter. item {
103104 ToastOverlayView (
104105 isPresented: Binding (
@@ -110,14 +111,15 @@ private struct ToastHostModifier: ViewModifier {
110111 }
111112 ) ,
112113 duration: item. duration,
114+ presentedOffset: placement. presentedOffset,
113115 action: item. action,
114116 onDismiss: item. onDismiss
115117 ) {
116118 ToastItemLabel ( item: item)
117119 }
118120 . id ( item. id)
119121 . padding ( . horizontal, 12 )
120- . padding ( . bottom, toastBottomInset)
122+ . padding ( . bottom, placement . bottomPadding ( toastBottomInset) )
121123 }
122124 }
123125 }
@@ -141,6 +143,42 @@ private struct ToastHostModifier: ViewModifier {
141143 }
142144}
143145
146+ private enum ToastPresentationPlacement {
147+ case top
148+ case bottom
149+
150+ static var current : ToastPresentationPlacement {
151+ ProcessInfo . processInfo. isiOSAppOnMac ? . top : . bottom
152+ }
153+
154+ var alignment : Alignment {
155+ switch self {
156+ case . top:
157+ return . top
158+ case . bottom:
159+ return . bottom
160+ }
161+ }
162+
163+ var presentedOffset : CGFloat {
164+ switch self {
165+ case . top:
166+ return 50
167+ case . bottom:
168+ return - 50
169+ }
170+ }
171+
172+ func bottomPadding( _ inset: CGFloat ) -> CGFloat {
173+ switch self {
174+ case . top:
175+ return 0
176+ case . bottom:
177+ return inset
178+ }
179+ }
180+ }
181+
144182private struct ToastItemLabel : View {
145183 let item : ToastItem
146184
@@ -161,6 +199,7 @@ private struct ToastItemLabel: View {
161199private struct ToastOverlayView < Label: View > : View {
162200 @Binding var isPresented : Bool
163201 let duration : TimeInterval
202+ let presentedOffset : CGFloat
164203 let action : ( ( ) -> Void ) ?
165204 let onDismiss : ( ( ) -> Void ) ?
166205 @ViewBuilder let label : ( ) -> Label
@@ -209,7 +248,7 @@ private struct ToastOverlayView<Label: View>: View {
209248 guard opacityValue == 0 else { return }
210249
211250 withAnimation ( . spring( response: 0.5 , dampingFraction: 1 , blendDuration: 0.0 ) ) {
212- yOffset = - 50
251+ yOffset = presentedOffset
213252 opacityValue = 1
214253 }
215254 }
0 commit comments