Add honeycomb pattern toggle and make theme switching reactive
Adds a toggleable honeycomb hexagonal grid overlay (matching the website pattern) that can be enabled independently of any theme via the Appearance screen. Uses a cached tiled UIImage approach consistent with the existing grain texture system. Replaces the destructive refreshID-based theme switching (which destroyed all NavigationStacks and dismissed sheets) with @Observable AppThemeSource. Color resolution now happens through Swift's Observation framework, so all views using Color.appPrimary etc. automatically re-render when the theme changes — no view identity reset needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -65,34 +65,11 @@ struct MainTabView: View {
|
||||
.onChange(of: authManager.isAuthenticated) { _, _ in
|
||||
selectedTab = .residences
|
||||
}
|
||||
.onChange(of: themeManager.currentTheme) { _, _ in
|
||||
updateTabBarAppearance()
|
||||
}
|
||||
.onAppear {
|
||||
// FIX_SKIPPED(F-10): UITabBar.appearance() is the standard SwiftUI pattern
|
||||
// for customizing tab bar appearance. The global side effect persists but
|
||||
// there is no safe alternative without UIKit hosting.
|
||||
|
||||
// Configure tab bar appearance
|
||||
let appearance = UITabBarAppearance()
|
||||
appearance.configureWithOpaqueBackground()
|
||||
|
||||
// Use theme-aware colors
|
||||
appearance.backgroundColor = UIColor(Color.appBackgroundSecondary)
|
||||
|
||||
// Selected item — uses Dynamic Type caption2 style (A-2)
|
||||
appearance.stackedLayoutAppearance.selected.iconColor = UIColor(Color.appPrimary)
|
||||
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
|
||||
.foregroundColor: UIColor(Color.appPrimary),
|
||||
.font: UIFont.preferredFont(forTextStyle: .caption2)
|
||||
]
|
||||
|
||||
// Normal item — uses Dynamic Type caption2 style (A-2)
|
||||
appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.appTextSecondary)
|
||||
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [
|
||||
.foregroundColor: UIColor(Color.appTextSecondary),
|
||||
.font: UIFont.preferredFont(forTextStyle: .caption2)
|
||||
]
|
||||
|
||||
UITabBar.appearance().standardAppearance = appearance
|
||||
UITabBar.appearance().scrollEdgeAppearance = appearance
|
||||
updateTabBarAppearance()
|
||||
|
||||
// Handle pending navigation from push notification
|
||||
if pushManager.pendingNavigationTaskId != nil {
|
||||
@@ -119,6 +96,27 @@ struct MainTabView: View {
|
||||
selectedTab = .residences
|
||||
}
|
||||
}
|
||||
|
||||
private func updateTabBarAppearance() {
|
||||
let appearance = UITabBarAppearance()
|
||||
appearance.configureWithOpaqueBackground()
|
||||
appearance.backgroundColor = UIColor(Color.appBackgroundSecondary)
|
||||
|
||||
appearance.stackedLayoutAppearance.selected.iconColor = UIColor(Color.appPrimary)
|
||||
appearance.stackedLayoutAppearance.selected.titleTextAttributes = [
|
||||
.foregroundColor: UIColor(Color.appPrimary),
|
||||
.font: UIFont.preferredFont(forTextStyle: .caption2)
|
||||
]
|
||||
|
||||
appearance.stackedLayoutAppearance.normal.iconColor = UIColor(Color.appTextSecondary)
|
||||
appearance.stackedLayoutAppearance.normal.titleTextAttributes = [
|
||||
.foregroundColor: UIColor(Color.appTextSecondary),
|
||||
.font: UIFont.preferredFont(forTextStyle: .caption2)
|
||||
]
|
||||
|
||||
UITabBar.appearance().standardAppearance = appearance
|
||||
UITabBar.appearance().scrollEdgeAppearance = appearance
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
||||
Reference in New Issue
Block a user