Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
e4202d5853
commit
8e91eed772
1
PRD.md
1
PRD.md
@ -435,7 +435,6 @@ TheNoiseClock/
|
||||
│ │ │ ├── ClockDisplayContainer.swift
|
||||
│ │ │ ├── ClockOverlayContainer.swift
|
||||
│ │ │ ├── ClockGestureHandler.swift
|
||||
│ │ │ ├── ClockTabBarManager.swift
|
||||
│ │ │ ├── ClockToolbar.swift
|
||||
│ │ │ ├── FullScreenHintView.swift
|
||||
│ │ │ └── Settings/
|
||||
|
||||
@ -35,6 +35,14 @@ struct ContentView: View {
|
||||
@State private var onboardingState = OnboardingState(appIdentifier: "TheNoiseClock")
|
||||
@State private var keepAwakePromptState = KeepAwakePromptState()
|
||||
|
||||
// MARK: - Computed Properties
|
||||
|
||||
/// Single source of truth for tab bar visibility - prevents race conditions
|
||||
/// Tab bar is ONLY hidden when on clock tab AND in display mode
|
||||
private var shouldHideTabBar: Bool {
|
||||
selectedTab == .clock && clockViewModel.isDisplayMode
|
||||
}
|
||||
|
||||
// MARK: - Body
|
||||
|
||||
var body: some View {
|
||||
@ -51,10 +59,6 @@ struct ContentView: View {
|
||||
|
||||
NavigationStack {
|
||||
AlarmView(viewModel: alarmViewModel)
|
||||
.toolbar(.visible, for: .tabBar)
|
||||
.onAppear {
|
||||
Design.debugLog("[AlarmView] onAppear - forcing tabBar visible")
|
||||
}
|
||||
}
|
||||
.tabItem {
|
||||
Label("Alarms", systemImage: "alarm")
|
||||
@ -63,10 +67,6 @@ struct ContentView: View {
|
||||
|
||||
NavigationStack {
|
||||
NoiseView()
|
||||
.toolbar(.visible, for: .tabBar)
|
||||
.onAppear {
|
||||
Design.debugLog("[NoiseView] onAppear - forcing tabBar visible")
|
||||
}
|
||||
}
|
||||
.tabItem {
|
||||
Label("Noise", systemImage: "waveform")
|
||||
@ -83,23 +83,27 @@ struct ContentView: View {
|
||||
onboardingState.reset()
|
||||
}
|
||||
)
|
||||
.toolbar(.visible, for: .tabBar)
|
||||
.onAppear {
|
||||
Design.debugLog("[ClockSettingsView] onAppear - forcing tabBar visible")
|
||||
}
|
||||
}
|
||||
.tabItem {
|
||||
Label("Settings", systemImage: "gearshape")
|
||||
}
|
||||
.tag(Tab.settings)
|
||||
}
|
||||
// SINGLE source of truth for tab bar visibility at TabView level
|
||||
// This eliminates race conditions from multiple views competing
|
||||
.toolbar(shouldHideTabBar ? .hidden : .visible, for: .tabBar)
|
||||
.onChange(of: selectedTab) { oldValue, newValue in
|
||||
Design.debugLog("[ContentView] Tab changed: \(oldValue) -> \(newValue)")
|
||||
Design.debugLog("[ContentView] Tab changed: \(oldValue) -> \(newValue), shouldHideTabBar: \(shouldHideTabBar)")
|
||||
if oldValue == .clock && newValue != .clock {
|
||||
Design.debugLog("[ContentView] Leaving clock tab, setting displayMode to false")
|
||||
// Immediately disable display mode when leaving clock tab
|
||||
// This is now a safety net - the computed property already handles visibility
|
||||
clockViewModel.setDisplayMode(false)
|
||||
}
|
||||
}
|
||||
.onChange(of: clockViewModel.isDisplayMode) { oldValue, newValue in
|
||||
Design.debugLog("[ContentView] isDisplayMode changed: \(oldValue) -> \(newValue), selectedTab: \(selectedTab), shouldHideTabBar: \(shouldHideTabBar)")
|
||||
}
|
||||
.accentColor(AppAccent.primary)
|
||||
.background(Color.Branding.primary.ignoresSafeArea())
|
||||
.fullScreenCover(item: activeAlarmBinding) { alarm in
|
||||
|
||||
@ -79,10 +79,7 @@ struct ClockView: View {
|
||||
.ignoresSafeArea() // Extend GeometryReader to full screen, we handle safe areas manually
|
||||
.toolbar(.hidden, for: .navigationBar)
|
||||
.statusBarHidden(true)
|
||||
.overlay {
|
||||
// Tab bar management overlay
|
||||
ClockTabBarManager(isDisplayMode: viewModel.isDisplayMode)
|
||||
}
|
||||
// Tab bar visibility is now controlled at ContentView level to prevent race conditions
|
||||
.simultaneousGesture(
|
||||
DragGesture(minimumDistance: 0)
|
||||
.onChanged { _ in
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
//
|
||||
// ClockTabBarManager.swift
|
||||
// TheNoiseClock
|
||||
//
|
||||
// Created by Matt Bruce on 9/8/25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Bedrock
|
||||
|
||||
/// Component that manages tab bar visibility for display mode
|
||||
/// Uses SwiftUI's native toolbar hiding for proper iPad compatibility
|
||||
struct ClockTabBarManager: View {
|
||||
|
||||
// MARK: - Properties
|
||||
let isDisplayMode: Bool
|
||||
|
||||
// MARK: - Body
|
||||
var body: some View {
|
||||
EmptyView()
|
||||
.toolbar(isDisplayMode ? .hidden : .automatic, for: .tabBar)
|
||||
.onAppear {
|
||||
Design.debugLog("[ClockTabBarManager] onAppear - isDisplayMode: \(isDisplayMode), tabBar: \(isDisplayMode ? "hidden" : "automatic")")
|
||||
}
|
||||
.onChange(of: isDisplayMode) { oldValue, newValue in
|
||||
Design.debugLog("[ClockTabBarManager] isDisplayMode changed: \(oldValue) -> \(newValue), tabBar: \(newValue ? "hidden" : "automatic")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Preview
|
||||
#Preview {
|
||||
ClockTabBarManager(isDisplayMode: false)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user