Hide the tab bar when pushing screens on iPhone as requested by the designs. (#4444)

Make the tab bar hide when pushing screens on iPhone as requested by the designs.

Annoyingly we couldn't simply add a second call to .toolbar(.hidden, for:.tabBar) on the pushed screens, but this way is automatic and there's still an override so it's good enough for now.
This commit is contained in:
Doug
2025-08-27 10:31:56 +01:00
committed by GitHub
parent 4ad7a93604
commit 4e53bd070d
2 changed files with 26 additions and 5 deletions

View File

@@ -16,6 +16,7 @@ import SwiftUI
var dismissalCallback: (() -> Void)?
}
@MainActor
@Observable class TabDetails {
/// A unique tab that identifies the tab for selection.
let tag: Tag
@@ -23,7 +24,11 @@ import SwiftUI
let icon: KeyPath<CompoundIcons, Image>
let selectedIcon: KeyPath<CompoundIcons, Image>
var badgeCount = 0
var barVisibility: Visibility = .automatic
var barVisibilityOverride: Visibility?
/// Provide the tab's split coordinator in here to have the tab bar automatically hidden
/// when pushing a child into the split view's details on iPhone/compact iPad.
weak var navigationSplitCoordinator: NavigationSplitCoordinator?
init(tag: Tag, title: String, icon: KeyPath<CompoundIcons, Image>, selectedIcon: KeyPath<CompoundIcons, Image>) {
self.tag = tag
@@ -31,6 +36,18 @@ import SwiftUI
self.icon = icon
self.selectedIcon = selectedIcon
}
func barVisibility(in horizontalSizeClass: UserInterfaceSizeClass?) -> Visibility {
if let barVisibilityOverride {
barVisibilityOverride
} else if horizontalSizeClass == .compact, navigationSplitCoordinator?.detailCoordinator != nil {
// Whilst we support pushing screens on the stack in the sidebarCoordinator, in practice
// we never do that, so simply checking that the detailCoordinator exists is enough.
.hidden
} else {
.automatic
}
}
}
// MARK: Tabs
@@ -202,6 +219,8 @@ import SwiftUI
}
private struct NavigationTabCoordinatorView<Tag: Hashable>: View {
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@Bindable var navigationTabCoordinator: NavigationTabCoordinator<Tag>
@State private var standardAppearance = UITabBarAppearance()
@@ -220,7 +239,7 @@ private struct NavigationTabCoordinatorView<Tag: Hashable>: View {
}
.tag(module.details.tag)
.badge(module.details.badgeCount)
.toolbar(module.details.barVisibility, for: .tabBar)
.toolbar(module.details.barVisibility(in: horizontalSizeClass), for: .tabBar)
}
}
.introspect(.tabView, on: .supportedVersions, customize: configureAppearance)

View File

@@ -106,9 +106,10 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
notificationManager: notificationManager,
stateMachineFactory: stateMachineFactory)
chatsTabDetails = .init(tag: HomeTab.chats, title: L10n.screenHomeTabChats, icon: \.chat, selectedIcon: \.chatSolid)
chatsTabDetails.navigationSplitCoordinator = chatsSplitCoordinator
if !appSettings.spacesEnabled {
chatsTabDetails.barVisibility = .hidden
chatsTabDetails.barVisibilityOverride = .hidden
}
let spacesSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator())
@@ -116,6 +117,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
navigationSplitCoordinator: spacesSplitCoordinator,
userIndicatorController: ServiceLocator.shared.userIndicatorController)
spacesTabDetails = .init(tag: HomeTab.spaces, title: L10n.screenHomeTabSpaces, icon: \.space, selectedIcon: \.spaceSolid)
spacesTabDetails.navigationSplitCoordinator = spacesSplitCoordinator
onboardingStackCoordinator = NavigationStackCoordinator()
onboardingFlowCoordinator = OnboardingFlowCoordinator(userSession: userSession,
@@ -272,8 +274,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
appSettings.$spacesEnabled
.combineLatest(userSession.clientProxy.spaceService.joinedSpacesPublisher)
.map { $0 && !$1.isEmpty ? .automatic : .hidden }
.weakAssign(to: \.chatsTabDetails.barVisibility, on: self)
.map { $0 && !$1.isEmpty ? nil : .hidden }
.weakAssign(to: \.chatsTabDetails.barVisibilityOverride, on: self)
.store(in: &cancellables)
}