TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

iOS 17 MapKit SwiftUI - Zoom out when the button selected

Forums > SwiftUI

Hi, I'm trying to mimic same behaviour of the Apple Maps app search button tapped zoom out functionality but I'm not able to do it.

In the Apple Maps app, after searching a place and tapping on the search result item it shows all search result item annotations while zooming out and both shows user's current location (blue dot) and the result annotations.

In my case, I have 2 POI buttons like a tabbar item and when the user tapped in them it passes query string to MKLocalSearch and showing the results through of it. What I want is, when the tabbar item like buttons tapped I have to zoom out on the both results and the user's current location (blue dot).

import SwiftUI
import MapKit

struct ContentView: View {

    @State private var cameraPosition: MapCameraPosition = .userLocation(followsHeading: true, fallback: .automatic)
    @State private var visibleRegion: MKCoordinateRegion?
    @State private var searchResults: [MKMapItem] = []
    @State private var selectedResult: MKMapItem?
    @State private var route: MKRoute?
    @State var isShowingBottomSheet = false
    @StateObject var locationManager = LocationManager.shared

    var body: some View {
        if locationManager.state == .notDetermined {
            LocationRequestView()
        } else if locationManager.state == .denied {
            LocationRequestDeniedView()
        } else {
            Map(position: $cameraPosition, selection: $selectedResult) {
                Annotation("Current location", coordinate: .userLocation) {

                }
                .annotationTitles(.hidden)

                ForEach(searchResults, id:\.self) {
                    Marker(item: $0)
                }
                .annotationTitles(.hidden)

                if let route {
                    MapPolyline(route)
                        .stroke(.blue, lineWidth: 5)
                }
            }
            .mapStyle(.standard(elevation: .realistic))
            .safeAreaInset(edge: .bottom) {
                HStack {
                    Spacer()
                    VStack(spacing: 0) {
                        if let selectedResult {
                            ItemInfoView(isShowing: $isShowingBottomSheet, route: $route, selectedTabBarButton: selectedTabBarButton, selectedResult: selectedResult, url: self.shareLocation())
                                .frame(height: 480)
                                .clipShape(RoundedRectangle(cornerRadius: 10))
                                .padding([.top, .horizontal])
                                .presentationContentInteraction(.scrolls)
                        }

                        Divider()

                        POIButtons(
                            position: $cameraPosition,
                            searchResults: $searchResults,
                            selectedTabBarButton: $selectedTabBarButton,
                            visibleRegion: visibleRegion
                        )
                            .padding(.top)
                    }

                    Spacer()
                }
                .background(.thinMaterial)
            }
            .onChange(of: searchResults) {
                withAnimation {
                    cameraPosition = .userLocation(followsHeading: true, fallback: .automatic)
                }
            }
            .onChange(of: selectedResult) {
                let region = MKCoordinateRegion(center: .userLocation, span: MKCoordinateSpan(latitudeDelta: 500, longitudeDelta: 500)) // I tried setting new MKCoordinateSpan values and change the cameraPosition = .region(with the new 'region')
                cameraPosition = .region(region)
                getDirections()

                if selectedResult?.pointOfInterestCategory == .evCharger {
                    selectedTabBarButton = "EV"
                } else {
                    selectedTabBarButton = "Gas"
                }
            }
            .onMapCameraChange { context in
                visibleRegion = context.region
            }
            .mapControls {
                MapUserLocationButton()
                MapCompass()
                MapScaleView()
            }
        }
    }

    func getDirections() {
        route = nil
        isShowingBottomSheet = true
        guard let selectedResult else { return }

        let location = locationManager.manager.location
        guard let coordinate = location?.coordinate else { return }

        let request = MKDirections.Request ()
        request.source = MKMapItem(placemark: MKPlacemark (coordinate: coordinate))
        request.destination = selectedResult
        Task {
            let directions = MKDirections(request: request)
            let response = try? await directions.calculate()
            route = response?.routes.first
        }
    }
}

2      

send me your LocationManager

2      

Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

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.