@@ -85,11 +85,19 @@ extension View {
8585}
8686
8787private struct ToastHostModifier : ViewModifier {
88+ @Environment ( \. safeAreaInsets) private var safeAreaInsets
89+ @State private var tabBarHeight = CGFloat . zero
8890 private let toastPresenter = ToastPresenter . presenter
8991
9092 func body( content: Content ) -> some View {
9193 content
9294 . frame ( maxWidth: . infinity, maxHeight: . infinity)
95+ . onAppear {
96+ updateTabBarHeight ( )
97+ }
98+ . onChange ( of: toastPresenter. item? . id) { _, _ in
99+ updateTabBarHeight ( )
100+ }
93101 . overlay ( alignment: . bottom) {
94102 if let item = toastPresenter. item {
95103 ToastOverlayView (
@@ -109,9 +117,28 @@ private struct ToastHostModifier: ViewModifier {
109117 }
110118 . id ( item. id)
111119 . padding ( . horizontal, 12 )
120+ . padding ( . bottom, toastBottomInset)
112121 }
113122 }
114123 }
124+
125+ private var toastBottomInset : CGFloat {
126+ max ( 0 , tabBarHeight - safeAreaInsets. bottom)
127+ }
128+
129+ @MainActor
130+ private func updateTabBarHeight( ) {
131+ let window = UIApplication . shared. connectedScenes
132+ . compactMap { $0 as? UIWindowScene }
133+ . flatMap ( \. windows)
134+ . first { $0. isKeyWindow }
135+
136+ guard let window else {
137+ tabBarHeight = . zero
138+ return
139+ }
140+ tabBarHeight = window. rootViewController? . visibleTabBarHeight ?? . zero
141+ }
115142}
116143
117144private struct ToastItemLabel : View {
@@ -279,3 +306,27 @@ private struct ToastCardView<Label: View>: View {
279306 . shadow ( color: Color ( . systemGray2) . opacity ( 0.4 ) , radius: 18 , x: 0 , y: 10 )
280307 }
281308}
309+
310+ @MainActor
311+ private extension UIViewController {
312+ var visibleTabBarHeight : CGFloat {
313+ var topViewController = self
314+
315+ while let presentedViewController = topViewController. presentedViewController {
316+ topViewController = presentedViewController
317+ }
318+
319+ if let tabBarController = ( topViewController as? UITabBarController ) ?? topViewController. tabBarController {
320+ return tabBarController. tabBar. isHidden ? . zero : tabBarController. tabBar. frame. height
321+ }
322+
323+ for child in topViewController. children {
324+ let childHeight = child. visibleTabBarHeight
325+ if 0 < childHeight {
326+ return childHeight
327+ }
328+ }
329+
330+ return . zero
331+ }
332+ }
0 commit comments