diff --git a/Loop/View Controllers/StatusTableViewController.swift b/Loop/View Controllers/StatusTableViewController.swift index 9144a7690..19cf257b9 100644 --- a/Loop/View Controllers/StatusTableViewController.swift +++ b/Loop/View Controllers/StatusTableViewController.swift @@ -643,7 +643,7 @@ final class StatusTableViewController: LoopChartsTableViewController { let statusRowMode = self.determineStatusRowMode() updateBannerAndHUDandStatusRows(statusRowMode: statusRowMode, newSize: currentContext.newSize, animated: animated) - tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: ActionTabBarMetrics.tableContentInset, right: 0) + updateTableBottomContentInset() redrawCharts() @@ -777,6 +777,17 @@ final class StatusTableViewController: LoopChartsTableViewController { override func viewDidLayoutSubviews() { updateStatusBar() + updateTableBottomContentInset() + } + + private func updateTableBottomContentInset() { + let bottomInset = ActionTabBarMetrics.tableContentInset( + isLandscape: view.bounds.width > view.bounds.height, + bottomSafeAreaInset: view.safeAreaInsets.bottom + ) + if tableView.contentInset.bottom != bottomInset { + tableView.contentInset.bottom = bottomInset + } } private func updateBannerRow(animated: Bool) { diff --git a/Loop/Views/StatusTableView.swift b/Loop/Views/StatusTableView.swift index 220e16eef..4855b9a78 100644 --- a/Loop/Views/StatusTableView.swift +++ b/Loop/Views/StatusTableView.swift @@ -215,6 +215,7 @@ struct ActionTabBar: UIViewRepresentable { tag: idx ) } + uiView.setNeedsLayout() } func makeCoordinator() -> Coordinator { Coordinator() } @@ -259,24 +260,8 @@ enum ActionTabBarMetrics { static let barHeight: CGFloat = 49 - static var bottomSafeAreaInset: CGFloat { - UIApplication.shared.connectedScenes - .compactMap { $0 as? UIWindowScene } - .flatMap { $0.windows } - .first { $0.isKeyWindow }? - .safeAreaInsets.bottom ?? 0 - } - - static var interfaceOrientation: UIInterfaceOrientation { - let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene } - let scene = scenes.first { $0.windows.contains { $0.isKeyWindow } } - ?? scenes.first { $0.activationState == .foregroundActive } - ?? scenes.first - return scene?.interfaceOrientation ?? .portrait - } - - static var tableContentInset: CGFloat { - guard !interfaceOrientation.isLandscape else { return 0 } + static func tableContentInset(isLandscape: Bool, bottomSafeAreaInset: CGFloat) -> CGFloat { + guard !isLandscape else { return 0 } if #available(iOS 26.0, *), bottomSafeAreaInset == 0 { return barHeight + 40 } @@ -287,13 +272,14 @@ enum ActionTabBarMetrics { struct LegacyTabBarBackground: ViewModifier { var isVisible: Bool = true + var bottomSafeAreaInset: CGFloat = 0 func body(content: Content) -> some View { if !isVisible { content .frame(height: 0) } else if #available(iOS 26.0, *) { - if ActionTabBarMetrics.bottomSafeAreaInset == 0 { + if bottomSafeAreaInset == 0 { content .frame(height: ActionTabBarMetrics.barHeight) .padding(.bottom, 16) @@ -315,7 +301,7 @@ struct LegacyTabBarBackground: ViewModifier { struct ActionTabView: View { - @State private var orientation: UIInterfaceOrientation + @Environment(\.verticalSizeClass) private var verticalSizeClass private let content: Content private let tabs: [ActionTab] @@ -326,24 +312,20 @@ struct ActionTabView: View { ) { self.content = content() self.tabs = tabs() - self.orientation = ActionTabBarMetrics.interfaceOrientation } var body: some View { - content - .safeAreaInset(edge: .bottom, spacing: 0) { - ActionTabBar(items: tabs, isHidden: !orientation.isPortrait) - .modifier(LegacyTabBarBackground(isVisible: orientation.isPortrait)) - } - .onAppear { - UIDevice.current.beginGeneratingDeviceOrientationNotifications() - orientation = ActionTabBarMetrics.interfaceOrientation - } - .onDisappear { - UIDevice.current.endGeneratingDeviceOrientationNotifications() - } - .onReceive(NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification)) { _ in - orientation = ActionTabBarMetrics.interfaceOrientation - } + let isPortrait = verticalSizeClass != .compact + return GeometryReader { geometry in + content + .safeAreaInset(edge: .bottom, spacing: 0) { + ActionTabBar(items: tabs, isHidden: !isPortrait) + .modifier(LegacyTabBarBackground( + isVisible: isPortrait, + bottomSafeAreaInset: geometry.safeAreaInsets.bottom + )) + } + } + .ignoresSafeArea(.keyboard) } }