Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions resources/xcode/NativePHP/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ struct ContentView: View {

var body: some View {
NativeSideNavigation(onNavigate: handleNavigation) {
WebViewLayoutContainer(onTabSelected: handleNavigation)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.safeAreaInset(edge: .top, spacing: 0) {
if uiState.hasTopBar() {
ZStack(alignment: .top) {
WebViewLayoutContainer(onTabSelected: handleNavigation)
.frame(maxWidth: .infinity, maxHeight: .infinity)

// Top bar overlay — inside side nav so it doesn't cover the drawer
if uiState.hasTopBar() {
VStack(spacing: 0) {
NativeTopBar(onNavigate: handleNavigation)
Spacer()
}
}
}
}
}

Expand Down Expand Up @@ -130,7 +135,7 @@ struct WebViewLayoutContainer: View {
// Single WebView instance - fills available space
WebView(shared: SharedWebView.shared, horizontalSizeClass: horizontalSizeClass)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea(.all, edges: uiState.hasTopBar() ? .horizontal : .all)
.ignoresSafeArea()

// Bottom navigation at bottom
NativeBottomNavigation(onTabSelected: onTabSelected)
Expand All @@ -140,7 +145,7 @@ struct WebViewLayoutContainer: View {
// No bottom nav - WebView fills entire screen
WebView(shared: SharedWebView.shared, horizontalSizeClass: horizontalSizeClass)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea(.all, edges: uiState.hasTopBar() ? [.horizontal, .bottom] : .all)
.ignoresSafeArea()
}
}
}
Expand Down Expand Up @@ -246,6 +251,9 @@ struct WebView: UIViewRepresentable {

let insets = windowScene?.windows.first?.safeAreaInsets ?? webView.window?.safeAreaInsets ?? .zero

// When top bar overlays the webview, add its height to the top inset
let topInset = insets.top + (NativeUIState.shared.hasTopBar() ? NativeUIState.topBarHeight : 0)

// Also get color scheme for CSS variable
let isDarkMode = windowScene?.windows.first?.traitCollection.userInterfaceStyle == .dark
let colorScheme = isDarkMode ? "dark" : "light"
Expand All @@ -254,7 +262,7 @@ struct WebView: UIViewRepresentable {
(function() {
// Set CSS variables directly on documentElement for immediate availability
if (document.documentElement) {
document.documentElement.style.setProperty('--inset-top', '\(insets.top)px');
document.documentElement.style.setProperty('--inset-top', '\(topInset)px');
document.documentElement.style.setProperty('--inset-right', '\(insets.right)px');
document.documentElement.style.setProperty('--inset-bottom', '\(insets.bottom)px');
document.documentElement.style.setProperty('--inset-left', '\(insets.left)px');
Expand Down Expand Up @@ -615,7 +623,7 @@ struct WebView: UIViewRepresentable {
}

func updateUIView(_ uiView: WKWebView, context: Context) {
// No manual insets needed - safeAreaInset handles topbar automatically
// Top bar overlays via ZStack; --inset-top includes its height when present
// Bottom nav uses its own safeAreaInset in WebViewLayoutContainer
}
}
Expand Down
3 changes: 3 additions & 0 deletions resources/xcode/NativePHP/NativeUI/NativeUIState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class NativeUIState: ObservableObject {
@Published var sideNavData: SideNavData?
@Published var topBarData: TopBarData?

// Standard UINavigationBar height + padding below
static let topBarHeight: CGFloat = 52

// Cache to prevent unnecessary updates
private var lastJsonString: String?

Expand Down
Loading