Display map or satellite imagery from your app's interface, call out points of interest, and determine placemark information for map coordinates using MapKit.

Posts under MapKit tag

146 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

MapCameraPosition camera region rect item all of them are nil
@State var position : MapCameraPosition = .userLocation(fallback: .region(.defaultRegion)) Map(position: $position) {} .onAppear { Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in print("check.position",position.camera,position.region,position.rect,position.item) } } All of the value are nil, so how do I get the current camera position?? check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil check.position nil nil nil nil It is always nil (even if I manually move around the Map with a finger)
1
0
167
Oct ’24
Apple Maps Not responding to scrolling, zooming, or tap gestures on custom pins
Scrolling and zooming I have two apps that utilize the Apple Maps and since I updated my xcode to use IOS18, some of the functionalities have either been missing or glitching, and when I roll back to IOS17.5, everything seems to work fine. When I use MKMapView and use mapView.isZoomEnabled = true mapView.isScrollEnabled = true Scrolling and zooming is still not working on IOS18 but IOS17.5 works fine. Clicking on custom annotations When I press on a custom annotation I add to the MapView, the gesture is sometimes recognized and most of the times not recognized. If I have 20 annotations, there is a possibility only 2 of them respond to tap gestures. Below is how I define the annotation. Annotation("Pin", coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude), anchor: .bottom) { Button(action: {print ("Pressed annotation"){ CustomPin() } }
0
0
164
Oct ’24
MKLocalSearch for cities - How to uniquely identify results?
I'm using MKLocalSearch with resultTypes set to .address to search for cities. The search results don't include an ID for each city, which I need for database storage (which from my understanding is the only thing we can store). If I can't store the city name, country, and coordinates in my database, and I'm not allowed to use third-party data (like a pre-made list of cities with coordinates), what are my options for uniquely identifying and storing these city results? Any suggestions would be greatly appreciated.
0
0
186
Oct ’24
Map Annotations not always receiving tap events on iOS 18.0
My app uses the SwiftUI Map control to display annotations. When annotations contain buttons AND the map has an .onTapGesture modifier, annotation button taps aren’t always recognized. Given the following ContentView, run it on an iOS device or simulator. Tap the buttons. Since iOS 18.0, some of the buttons won't respond to tap. I've also tried using the onTapGesture instead of a button, and that shows the same issue. This was not a problem under iOS 17.x: it has only shown up for my users since updating to iOS 18. Additionally, this issue does not occur when running on either macOS 15.0 or visionOS 2.0 when running in "designed for iPad" mode. Note that there was previously a tap issue on VisionOS 1.x (designed for iPad), where no tap gestures were received by annotations. I'm curious if this issue could be related. I have filed a report in Feedback Assistant (FB15273909). struct ContentView: View { private let center = CLLocationCoordinate2D(latitude: 37.77925, longitude: -122.41924) @State private var label: String = "tap a button" @State private var locations: [Location] = [] var body: some View { Map { ForEach(locations) { location in Annotation(location.name, coordinate: location.coordinate) { Button(location.name) { print("\(location.name) tapped") label = "\(location.name) tapped" } .buttonStyle(.borderedProminent) } .annotationTitles(.hidden) } } .onTapGesture { point in print("Map tapped") label = "map tapped" } .safeAreaInset(edge: .top) { Text(label) .padding() .background(.thinMaterial) .clipShape(.rect(cornerRadius: 10)) } .navigationTitle("Test Page") .navigationBarTitleDisplayMode(.inline) .task { for index in 1...16 { locations.append(Location(name: "location \(index)", coordinate: CLLocationCoordinate2D(latitude: center.latitude + Double.random(in: -0.02...0.02), longitude: center.longitude + Double.random(in: -0.02...0.02)))) } } } private struct Location: Identifiable { let id: UUID = UUID() let name: String let coordinate: CLLocationCoordinate2D } } #Preview { ContentView() }
1
1
249
Oct ’24
MKLocalSearch for cities not returning location identities
Hi fellow developers, I'm encountering an issue when using MKLocalSearch to search for cities. Here's my setup: I'm using MKLocalSearch with an MKLocalSearch.Request object. I've set the resultTypes to .address to focus on address results. The problem: When I receive the search response, it includes the locations as expected. However, these locations don't have an identity or alternative identities. Questions: Is this the expected behavior when searching for cities? Without an identity, how can I uniquely identify and store these city results in my database? Would it be appropriate to store the city name, country, and coordinates instead? Thanks in advance!
0
0
217
Sep ’24
MapAnnotation Position
I am working on a MapView with MapAnnotation on the Map and am having difficulty getting the MapAnnotation to function properly when selected. In my code, I want the MapAnnotation selected to be to the front if it is behind or partially blocked by another annotation. I have tried using a zIndex but this does not appear to work. Below is my MapView code along with a screenshot of the issue. Any help would be greatly appreciated. struct HospitalMapView: View { @StateObject var viewModel = HospitalViewModel() @State private var showSearchView = false @State private var showListView = false @State private var selectedTab: Int = 0 var body: some View { ZStack { VStack(spacing: 0) { TopTabView() // Map that updates the visible hospitals when the user moves or adjusts the map Map(coordinateRegion: $viewModel.region, interactionModes: .all, annotationItems: viewModel.filteredHospitals) { hospital in MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: hospital.latitude, longitude: hospital.longitude)) { RoundedRectangle(cornerRadius: 40) .fill(viewModel.colorForPercentile(viewModel.calculatePercentile(for: hospital, in: viewModel.filteredHospitals))) .frame(width: 70, height: 30) // Maintain consistent size, adjust if necessary .overlay( Text("$\(Int(hospital.baseCharge / 1000))K") .foregroundColor(.white) .bold() ) .overlay( RoundedRectangle(cornerRadius: 40) .stroke(Color.blue, lineWidth: viewModel.selectedHospital == hospital ? 3 : 0) ) .onTapGesture { viewModel.selectHospital(hospital) // Move the selected hospital to the end of the list to bring it to the front viewModel.bringHospitalToFront(hospital) viewModel.showBottomSheet = true } .scaleEffect(viewModel.selectedHospital == hospital ? 1.1 : 1.0) // Highlight the selected hospital .zIndex(viewModel.selectedHospital == hospital ? 1 : 0) // Set the zIndex higher for the selected hospital .animation(.easeInOut, value: viewModel.selectedHospital) // Smooth transition } } .onAppear { // Initial update of visible hospitals when the map appears viewModel.updateFilteredHospitals() } .onChange(of: viewModel.region) { _ in // Update the visible hospitals as the user changes the map region viewModel.updateFilteredHospitals() } .edgesIgnoringSafeArea(.all) } // Hospital count display hovering over the map Text("\(viewModel.filteredHospitals.count) Hospitals") .font(.subheadline) .foregroundColor(.white) .padding(8) .background(Color.black.opacity(0.6)) .cornerRadius(10) .padding(.top, -315) // Adjust padding to position correctly below the TopTabView .zIndex(1) // Ensure it's above the map if let selectedHospital = viewModel.selectedHospital, viewModel.showBottomSheet { BottomSheetView(isOpen: $viewModel.showBottomSheet, maxHeight: UIScreen.main.bounds.height * 0.3) { SummaryTabView(selectedHospital: Binding( get: { selectedHospital }, set: { newValue in viewModel.selectHospital(newValue) } )) } .transition(.move(edge: .bottom)) .animation(.spring()) } } .safeAreaInset(edge: .bottom) { BottomTabView(selectedTab: $selectedTab, showListView: $showListView, showSearchView: $showSearchView, onSearchSelected: { showSearchView = true showListView = false }, onHomeSelected: { showSearchView = false showListView = false }, onListSelected: { showListView = true showSearchView = false }) } .fullScreenCover(isPresented: $showSearchView) { SearchView(viewModel: viewModel, showSearchView: $showSearchView, selectedTab: $selectedTab, showListView: $showListView) } .fullScreenCover(isPresented: $showListView) { ListView(selectedTab: $selectedTab, showListView: $showListView, showSearchView: $showSearchView) .environmentObject(viewModel) } .environmentObject(viewModel) } }
0
0
255
Sep ’24
How to find coordinates for Map Overlay placement
Hello everyone - I created a navigation app that uses a map overlay for finite spaces such as a zoo. I get these overlays created by a designer in .PNG - the designer creates the overlays and then puts a square or rectangle box around the overlay because it needs to be placed in 9 pieces making it easier to render when user zooms in/out... I used to have my Swift devs place the overlay using the correct coordinates that were given by a single person, but we never found out exactly how they did it - and now I can no longer contact the dev. Can anyone help me by telling me how I can get the coordinates (I am thinking that any opposite vertices would do - and maybe the center point?). I also have a few other questions: a. Is .SVG best to use for map overlays? b. Should we continue to chop into 9 pieces for faster rendering or is there a better way to do this in MapKit (we have been doing this for 4 years, maybe there is a better way) I would be so thankful for any help. Best, Michael
2
0
255
Sep ’24
Image using MKLookAroundSnapshotter with Updated Scene
I'm trying to create a UIImage from a MKLookAroundScene, after the user has moved the scene, by looking (and moving) around. Is this possible? When I use MKLookAroundSnapshotter with the modified scene, I always get an image of the original (starting) scene. STEPS TO REPRODUCE Create a scene using MKLookAroundSceneRequest with coordinates. Use LookAroundPreview with a binding to MKLookAroundScene to get changes to the scene (based on looking around). User begins LookAround, moving the scene location and view. User ends LookAround The preview displays the updated scene properly. The scene's cameraFrameOverride values reflect the pitch, roll, yaw, and location changes. Pass the updated scene to MKLookAroundSnapshotter to get an image. Display the Image. The Image is the original scene (not what is displayed in the preview).
1
0
276
Sep ’24
MKScaleView doesn't update changing area programmatically
I have a MKMapView with a MKScaleView. If I visualise a generic map I have the scale in km. When I change the MKMapRect using visibleMapRect, the scale doesn't change. If I use setVisibleMapRect(_ mapRect: MKMapRect, animated animate: Bool), the scale change but not to the correct one. For example, it shows a scale saying one inch corresponds to 250 m while it is 150 m. The same issue of I use MKCoordinateRegion. Instead, if I zoom in or zoom out pinching on the map, the scale updates correctly. Am I doing something wrong? How can I fix this? Sample code: import UIKit import MapKit let CORNER_RADIUS: CGFloat = 8.0 let METERS_PER_MILE: Double = 1609.344 class PIAnnotation: NSObject, MKAnnotation { var coordinate: CLLocationCoordinate2D private(set) var title: String? private(set) var subtitle: String? init(location: CLLocationCoordinate2D, title: String? = nil, subtitle: String? = nil) { coordinate = location self.title = title self.subtitle = subtitle } } class PISimpleMapView: MKMapView { private let HALF_MAP_SIDE_MULTIPLIER: Double = 1.4 private let pinIdentifier = "pinIdentifier" private var scaleView: MKScaleView? typealias PinAnnotationView = MKMarkerAnnotationView // MKPinAnnotationView required init?(coder: NSCoder) { super.init(coder: coder) inizialize() } override init(frame: CGRect) { super.init(frame: frame) inizialize() } func inizialize() { layer.cornerRadius = CORNER_RADIUS register(PinAnnotationView.self, forAnnotationViewWithReuseIdentifier: pinIdentifier) addScale() } private func addScale() { let scale = MKScaleView(mapView: self) scale.translatesAutoresizingMaskIntoConstraints = false scale.scaleVisibility = .visible // always visible addSubview(scale) let guide = safeAreaLayoutGuide NSLayoutConstraint.activate([ scale.leftAnchor.constraint(equalTo: guide.leftAnchor, constant: 16.0), scale.rightAnchor.constraint(equalTo: guide.centerXAnchor), scale.topAnchor.constraint(equalTo: guide.topAnchor), scale.heightAnchor.constraint(equalToConstant: 20.0) ]) scaleView?.removeFromSuperview() scaleView = scale } func displayPinOnMap(location: CLLocation) { let annotation = PIAnnotation(location: location.coordinate, title: "Sample", subtitle: nil) addAnnotation(annotation) // Position the map so that all overlays and annotations are visible on screen. visibleMapRect = visibleArea(from: annotation) // setVisibleMapRect(visibleArea(from: annotation), animated: true) // region = MKCoordinateRegion(visibleArea(from: annotation)) } private func visibleArea(from annotation: PIAnnotation) -> MKMapRect { let annotationPoint = MKMapPoint(annotation.coordinate) return MKMapRect(x: annotationPoint.x - HALF_MAP_SIDE_MULTIPLIER * METERS_PER_MILE, y: annotationPoint.y - HALF_MAP_SIDE_MULTIPLIER * METERS_PER_MILE, width: HALF_MAP_SIDE_MULTIPLIER * 2.0 * METERS_PER_MILE, height: HALF_MAP_SIDE_MULTIPLIER * 2.0 * METERS_PER_MILE) } }
5
0
465
Sep ’24
SwiftUI and MapKit - Find address from coordinates
I've seen a lot of posts around the internet about getting coordinates from an address, but none about how to do the opposite. What I would like to do is allow a person to drop a pin and then programmatically look up the address closest to the pin. Like if I drop a pin inside a mall on the map I would like to capture the address to the mall. Does anyone know how this could be done?
2
0
371
Aug ’24
LongPressGesture to add and select Map Pin
Hi there! I am tying to add and select a map pin using view long press when the gesture is begin. However after adding and selecting the pin it got deselected immediately, my assumption that it's conflicting when the original map gesture and it's deselecting the pin on the map (like if a pin was selected and you click anywhere on the map to deselect it). Note that if I increase minimumPressDuration for the UILongPressGestureRecognizer it works fine, but I want the value at 0.5 so the pin is quickly added. here is the full code: import SwiftUI import MapKit struct ContentView: View { @State var selection: CustomMapSelection? @State private var longPressPosition: CGPoint = .zero @State private var pinCoordinate: CLLocationCoordinate2D? var body: some View { MapReader { proxy in Map(selection: $selection) { if let pinCoordinate { Marker("Custom Location", coordinate: pinCoordinate) .tag(CustomMapSelection(coordinate: pinCoordinate)) } } .gesture(LongPressGestureRecognizer(position: $longPressPosition)) .onChange(of: longPressPosition) { if let coordinate = proxy.convert(longPressPosition, from: .global) { pinCoordinate = coordinate selection = CustomMapSelection(coordinate: coordinate) } } } } } struct CustomMapSelection: Hashable { let latitude: Double let longitude: Double init(coordinate: CLLocationCoordinate2D) { latitude = coordinate.latitude longitude = coordinate.longitude } } struct LongPressGestureRecognizer: UIGestureRecognizerRepresentable { @Binding var position: CGPoint func makeCoordinator(converter: CoordinateSpaceConverter) -> Coordinator { Coordinator() } func makeUIGestureRecognizer(context: Context) -> UILongPressGestureRecognizer { let recognizer = UILongPressGestureRecognizer() recognizer.delegate = context.coordinator // if you make the minimumPressDuration above 2, it works fine and the selection doesn't cancel recognizer.minimumPressDuration = 0.5 return recognizer } func handleUIGestureRecognizerAction(_ recognizer: UILongPressGestureRecognizer, context: Context) { if recognizer.state == .began { let position = recognizer.location(in: recognizer.view) self.position = position } } class Coordinator: NSObject, UIGestureRecognizerDelegate { func gestureRecognizer( _ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer ) -> Bool { return true } } } #Preview { ContentView() }
1
0
386
Aug ’24
Loading large amounts of coordinates and annotations to a map?
My query might return 20,000 coordinates. Does MapKit JS try to load all the coordinates at once into the map or does it only load what’s in the viewport of the map if we were to load 20,000 annotations into the say something like “landmark data” const? We have 900,000 coordinates to load into Los Angeles and are planning how we will do this. Obviously we can’t load 900,000 coordinates at once without performance issues, but some query’s return 20,000 results. Can someone point me to some information about large datasets and MapKit js or let me know if it’s handled and already built in to not try to load that many locations at once?
0
0
328
Aug ’24
Is it possible to display a live 3D view of Google Maps in a Vision Pro app?
Hi everyone, I’m exploring the idea of displaying a live 3D view of Google Maps in a Vision Pro app using SwiftUI and RealityKit. I want users to be able to interact with the map, including panning, zooming in and out, and exploring different areas in a fully immersive environment. Is this technically possible within the Vision Pro ecosystem? If so, what would be the recommended approach to implement this? If not, are there any alternative methods or platforms that could provide a similar experience? Thanks in advance for your insights! Best, Siddharth
1
0
727
Aug ’24
Swift 6 Concurrency Errors with MKLocalSearchCompleterDelegate results
Has anyone found a thread-safe pattern that can extract results from completerDidUpdateResults(MKLocalSearchCompleter) in the MKLocalSearchCompleterDelegate ? I've downloaded the code sample from Interacting with nearby points of interest and notice the conformance throws multiple errors in Xcode 16 Beta 5 with Swift 6: extension SearchDataSource: MKLocalSearchCompleterDelegate { nonisolated func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { Task { let suggestedCompletions = completer.results await resultStreamContinuation?.yield(suggestedCompletions) } } Error: Task-isolated value of type '() async -> ()' passed as a strongly transferred parameter; later accesses could race and Error: Sending 'suggestedCompletions' risks causing data races Is there another technique I can use to share state of suggestedCompletions outside of the delegate in the code sample?
2
1
966
Aug ’24