iosswiftmacosswiftuimacos-sequoia

Gap at top on Designed for iPad Mac apps


There appears to be a space above the TabBar on the macOS "Designed for iPad" apps in running on macOS 15.4 (24E248) Xcode 16.2 or 16.3 , this doesn’t happen on macOS 15.3 and doesn't appear on iOS, or other platforms.

It happens with this code:

import SwiftUI

@main
struct TestMacTabApp: App {
  var body: some Scene {
    WindowGroup {
      Color.pink
    }
  }
}

gap shown above content in simple app

It also happens when putting a NavigationSplitView inside a TabView but not if there is a NavigationStack inside the TabView

import SwiftUI

struct ContentView: View {
  var body: some View {
    TabView {
      
      NavigationSplitView {
        Text("Sidebar")
          .navigationTitle("Green")
          .navigationBarColor(backgroundColor: Color.orange, titleColor: .black)
          .navigationBarTitleDisplayMode(.inline)
      } detail: {
        Color.green.overlay (
          Text("Hello, world!")
            .padding()
        )
        .navigationTitle("Green")
        .navigationBarColor(backgroundColor: Color.orange, titleColor: .black)
        .navigationBarTitleDisplayMode(.inline)
      }
      .tabItem { Label(title: { Text("Green") }, icon: { Image(systemName: "heart") }) }
      
      NavigationStack {
        Color.blue.overlay (
          Text("Hello, world!")
            .padding()
        )
        .navigationTitle("Blue blue blue blue blue blue blue blue blue blue blue blue")
        .navigationBarColor(backgroundColor: Color.orange, titleColor: .black)
        .navigationBarTitleDisplayMode(.inline)
      }
      .tabItem { Label(title: { Text("Blue") }, icon: { Image(systemName: "heart") }) }
    }
    .environment(\.horizontalSizeClass, .regular)
  }
}

struct NavigationBarModifier: ViewModifier {
  
  var backgroundColor: UIColor?
  var titleColor: UIColor?
  
  
  init(backgroundColor: Color, titleColor: UIColor?) {
    self.backgroundColor = UIColor(backgroundColor)
    
    let coloredAppearance = UINavigationBarAppearance()
    coloredAppearance.configureWithTransparentBackground()
    coloredAppearance.backgroundColor = UIColor(backgroundColor)
    coloredAppearance.titleTextAttributes = [.foregroundColor: titleColor ?? .white]
    coloredAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor ?? .white]
    coloredAppearance.shadowColor = .clear
    
    UINavigationBar.appearance().standardAppearance = coloredAppearance
    UINavigationBar.appearance().compactAppearance = coloredAppearance
    UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
    UINavigationBar.appearance().tintColor = titleColor
  }
  
  func body(content: Content) -> some View {
    ZStack{
      content
      VStack {
        GeometryReader { geometry in
          Color(self.backgroundColor ?? .clear)
            .frame(height: geometry.safeAreaInsets.top)
            .edgesIgnoringSafeArea(.top)
          Spacer()
        }
      }
    }
  }
}

extension View {
  func navigationBarColor(backgroundColor: Color, titleColor: UIColor?) -> some View {
    self.modifier(NavigationBarModifier(backgroundColor: backgroundColor, titleColor: titleColor))
  }
}

#Preview {
  ContentView()
}

some nav bar appearance code to make it easier to see what's happening

gap shown above content in Split View no gap shown with nav stack


Solution

  • try with ignoresSafeArea()

    @main
    struct TestMacTabApp: App {
      var body: some Scene {
        WindowGroup {
          Color.pink
            .ignoresSafeArea()
        }
      }
    }