3

I am working on a SwiftUI app which uses both TabView and NavigationView. One of the views is responsible for presenting a Map from MapKit and it is meant to take all available space. I would like it to extend beyond TabBar and NavigationBar, so that I can see the map's content through the bars' standard translucent material, just like on this screenshot from the Apple Store app:

Apple Store App Screenshot

I tried using .ignoresSafeArea() modifier on the Map, but then the bars had no background material at all, just the buttons and navigation title were visible, like this:

Demo View Screenshot

It doesn't seem to be a problem specific to the structure of my app - I tried making a new, independent view with those two bars and still got the same results. Here is the code of that sample view:

import MapKit
import SwiftUI

struct SwiftUIView: View {
    @State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 50, longitude: 20),
        span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
    )
    
    var body: some View {
        TabView {
            NavigationView {
                Map(coordinateRegion: $region)
                    .ignoresSafeArea()
                    .navigationTitle("Map")
            }
            .tabItem {
                Label("Map", systemImage: "map")
            }
        }
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

Is there something important I am missing or is there a bug in the Map component?

  • I have the exact same issue, did you find a way to achieve it? – Mathieu Mar 31 '22 at 23:52
  • @Mathieu, unfortunately, I did not solve the problem. What I discovered, however, was that the cause lies in UIKit applying incorrect UINavigationBarAppearance to both top and bottom bar. I tried setting those appearances manually, but with no success. – Kamil Chmielewski Apr 01 '22 at 22:51
  • Too bad, thanks for the answer. I'll post here if I ever find anything. – Mathieu Apr 02 '22 at 01:14

2 Answers2

2

I solved this problem by adding

.safeAreaInset(edge: .bottom) {
  Color.clear
    .frame(height: 0)
    .background(.ultraThinMaterial)
}

to the MapView

reubn
  • 123
  • 1
  • 8
2

You can fix it by adding a ScrollView background:

      ZStack {
      ScrollViewReader { proxy in
        ScrollView {
          Spacer()
            .frame(height: 10000)
            .id(1)
          Spacer()
            .frame(height: 10000)
            .id(2)
          Spacer()
            .frame(height: 10000)
            .id(3)
        }
        .onAppear {
          proxy.scrollTo(2)
        }
      }
      .ignoresSafeArea()
        
        Map(...)
          .ignoresSafeArea()
      }

This makes the toolbar appearance to be as desired - as it is a scroll view that has both top and bottom overlap..

Nicolas Degen
  • 1,522
  • 2
  • 15
  • 24
  • 1
    Thank you, this helped solve my problem in half (for the Tab Bar only), but I managed to fix it fully by adding `.navigationBarTitleDisplayMode(.inline)` modifier to the MapView - according to the latest iOS Navigation Bar title styles the background doesn't show when in the `.large` display mode. – Kamil Chmielewski Apr 02 '23 at 16:35
  • Good point! Did never use it with a large nav bar and had never realized it would be an issue:) – Nicolas Degen Apr 02 '23 at 18:51