WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

MapKit Map Buggy in NavigationLink

Forums > SwiftUI

TL;DR -- Below I have used Map in two very simple ways in the example below but one is buggy and the other is not. Why?

I've used Map(coordinateRegion:) successfully before but I'm running into an issue now where if I use that map as the destination of a NavigationLink then the scrolling is terrible. If I make a new view (here MyMapView) that has nothing more than a @Binding to the region it suddely works smoothly. What is going on here to cause this issue? I'm not having luck solving this problem in the same way in my bigger app but it seems to be the same problem so if I can understand the root of it here I can hopefully apply it back to the other project. On the simulator the "slow" version often works but on device it is obviously bad every time.

import SwiftUI
import MapKit

struct ContentView: View {
    @State private var region1 = MKCoordinateRegion(.world)
    @State private var region2 = MKCoordinateRegion(.world)

    var body: some View {
        NavigationView {
            List {
                NavigationLink {
                    Map(coordinateRegion: $region1)
                } label: {
                    Text("Slow Map")
                }
                NavigationLink {
                    MyMapView(region: $region2)
                } label: {
                    Text("Good Map")
                }
            }
        }
    }
}

struct MyMapView: View {
    @Binding var region: MKCoordinateRegion

    var body: some View {
        Map(coordinateRegion: $region)
    }
}

   

I think the reason is that when you pass in the coordinateRegion into Map when you scroll the map it need to update the @State however it does not have access to region1 as it in a new view, however when you use MyMapView it has access to region as it in the same struct

If you look at the "Slow Map" you will see you can not scroll the map at all (not just buggy!). It trys to move it but can not update the coordinates so in snap back to orginal.

Hope that is understandable

   

I might be missing a nuance in your description but I don't see how this explains the problem in any more detail than what I have shown in the code. The slow map can be moved even though it's not very easy.

   

I found some related discussion (linked below) that explains it somewhat well but it then raises the question for me of why it does work for @Binding. In any case, what I've done is switched to the UIKit version and then used mapView(_:regionDidChangeAnimated:) and it works almost perfectly so I'm just going to use that for now.

https://stackoverflow.com/questions/67859494/swiftui-how-to-get-rid-of-constant-initialization-of-views-linked-through-naviga

https://stackoverflow.com/questions/60278829/obervableobject-being-init-multiple-time-and-not-refreshing-my-view

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.