I am trying to set contraints for MKMapView but whenever I control click I get the outlets menu instead! Works for labels and all else, but not for the map.
I have a standard UITableViewController and I have added an MKMapKit map neatly on the top half of the screen (and the table in the bottom half).
During runtime, if we scroll through the table records, the map scrolls up as well.
What I wanted to do was have the map static, not scrolling, while I scroll the table.
Any ideas on how to accomplish this, please?
Post not yet marked as solved
when using the MapKit.Map to display multiple Annotation overlapping, everything works properly whether you use MapPin, MapMarker or MapAnnotation.
The tricky part is to bring an annotation to the front once you clickOnAnnotation.
Considering MapPin, MapMarker or MapAnnotation are MapAnnotationProtocol Custom Types, which respectively, defined as follow in the official documentation:
// Available when SwiftUI is imported with MapKit
@available...
public protocol MapAnnotationProtocol {}
@available...
public struct MapMarker : MapAnnotationProtocol {
public init(coordinate: CLLocationCoordinate2D, tint: Color? = nil)
}
// Available when SwiftUI is imported with MapKit
@available...
public struct MapPin : MapAnnotationProtocol {
public init(coordinate: CLLocationCoordinate2D, tint: Color? = nil)
}
// Available when SwiftUI is imported with MapKit
@available...
public struct MapAnnotation<Content> : MapAnnotationProtocol where Content : View {
public init(coordinate: CLLocationCoordinate2D, anchorPoint: CGPoint = CGPoint(x: 0.5, y: 0.5), @ViewBuilder content: () -> Content)
}
How can we implement a CustomView which also implements this protocol but provides us also with the needed properties which allows us to access the cooler feature of The Map (like zIndex of an annotation as a start)?
I know we can still use UIViewRepresentable but that is not my goal, unless ...
helpfull Links:
Apple Documentation
StackOverflow - Related Topic
Post not yet marked as solved
func zoomOne() {
region.span.latitudeDelta = 10_000
region.span.longitudeDelta = 10_000
}
func zoomIn() {
region.span.latitudeDelta /= 2
region.span.longitudeDelta /= 2
}
func zoomOut() {
region.span.latitudeDelta *= 2
region.span.longitudeDelta *= 2
}
My MacOS app has three methods for adjusting the zoom on a MapKit map display. Each is tied to a separate view Button.
zoomIn() and zoomOut() work as expected, but when the program calls zoomOne(), Xcode breaks and reports a runtime issue in the Issue Navigator:
NSHostingView is being laid out reentrantly while rendering its SwiftUI content. This is not supported and the current layout pass will be skipped.
As a fix, I tried embedding the zoomOne() region update in a DispatchQueue.main.async closure, but it still failed with the same issue.
Thanks, Mark
Post not yet marked as solved
I have an app that displays a MapKit map with a Text as an a MapAnnotation. When the map is first displayed, the map is centered on the coordinates of the MapAnnotation and once things settle down, the CPU usage reported by Xcode's Debug Navigator goes to 0%.
If the map is dragged or zoomed so that the MapAnnotation is not at the center, the CPU usage goes up during the motion, but does not go back to 0%, but settles down to a few per cent. If you look closely at the map, you can sometimes see that the MapAnnotation is vibrating. Other map features do not appear to move.
I assume that the MapAnnotation is not tied to a fixed map location as are the map features and if the MapAnnotation is not at the center, its display position needs to be constantly recalculated.
Hello,
I would like to know if there is a way to disable the focus on a new added annotation on mapkit js.
I have a loop that display annotation and every time the new annotation shows up, the map move the camera and set a super-dupper zoom on the new annotation. This is very annoying.
Map initialisation :
var map = new mapkit.Map("map", {
region: region,
showsCompass: mapkit.FeatureVisibility.Hidden,
showsZoomControl: true,
showsMapTypeControl: true,
showsUserLocation: true,
});
_
New annotation :
chasseur = new mapkit.Coordinate(48.8607, 2.3421);
ChasseurAnnotation = new mapkit.MarkerAnnotation(chasseur, {
color: "#001788",
title: "Chasseur",
glyphText: "\u{1F6A8}" // POLICE
});
map.showItems([ChasseurAnnotation]);
_
Thanks a lot for your further responses.
Post not yet marked as solved
Are there any solutions to convert floor plans to IMDF files for Indoor Mapping (or at least plans to create a conversion tool)?
Most of the tools such as ERSI and Autodesk seem to be developed more for building engineers and architects. Is there anything for content managers to ingest floor plans (provided by our facilities dept), and create and update locations in buildings as they change, and publish to an in-app Apple map implementation?
Thanks in advance,
Scott
I used the Xcode template to create a Mac App. I then modified ContentView.swift
import SwiftUI
import MapKit
struct ContentView: View {
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: 0.0,
longitude: 0.0),
span: MKCoordinateSpan(
latitudeDelta: 0.5,
longitudeDelta: 0.5))
var body: some View {
Map(coordinateRegion: $region)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
When I run this code, Xcode reports a runtime error:
Modifying state during view update, this will cause undefined behavior.
It is reported on Thread 1.
This is identified with a purple warning in the issue navigator, but there is no indication of the location of the error in the source code editor.
The actual map coordinates don't matter. I get the same error with different coordinates.
Xcode 13.3.1
OSX Monterey 12.3.1
Mac Mini M1
P.S. When I cut the example code above from Xcode and pasted it into this message, it added extra line breaks between each line (which I manually removed). Is there a way to have the code paste as it was in Xcode?
P.P.S. When I listed the software and hardware info, If I don't make it a bulleted list, the ended up being displayed on one line. If I put blank lines between them, the blank lines are displayed. Is there any way to make a vertical list without bullets?
Post not yet marked as solved
I've copied a couple of tutorial Mac OS apps using MapKit. One uses SwiftUI, the other AppKit. Both initially display a map and allow the user to pan and zoom with the mouse. According to XCode's debug navigator, once the user has stopped panning or zooming, the CPU usage goes to 0%.
Both apps allow the user to enter a location and add a MapAnnotation to the map.
On the AppKit version, once the annotation is added, the CPU usage drops back to 0%, but on the SwiftUI version, the CPU usage remains around 5 - 15%. If you look closely at the SwiftUI version, you can see the annotation vibrating by a pixel or so on the display. It seems to me that the display is being constantly updated.
If the annotation is removed, the CPU usage goes back to 0%
I placed a breakpoint in the code that draws the annotation in the SwiftUI version. When adding an annotation, the breakpoint is hit twice, but then no more, so I don't think the CPU is spending time in the Swift code.
Xcode 13.3.1
OSX Monterey 12.3.1
Mac Mini M1
Post not yet marked as solved
Hi,
if I use mapkit how can I show the longitude and latitude of the center of the map?
I don't mean the current location.
I just need the coordinates of the shown position.
Post not yet marked as solved
I would like the MKMapItem returned from MKLocalSearch to contain an "altitude" property. In order to achieve this, I've decided to create a subclass for MKMapItem.
class MapItemGeoSpatial: MKMapItem {
var altitude: Measurement<UnitLength>
public init(placemark: MKPlacemark, altitude: Measurement<UnitLength>) {
self.altitude = altitude
super.init(placemark: placemark)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
While the above implementation compiles, it results in a fatal error when attempting to initialise MapItemGeoSpatial.
Fatal error: Use of unimplemented initializer 'init()' for class 'MapItemGeoSpatial'
The above error occurs during the super.init(placemark:) call.
The altitude property is set by me (the source of this value is not relevant to this discussion, but it is determined by extracting the coordinates from MKMapItem) via the designated initialiser. I understand that MKLocalSearch has nothing to do with altitude, but I, as the client, found it desirable to contain this information when it is passed to other areas of my project. This is the primary reason why I chose to subclass MKMapItem, in an attempt to "inherit" all it's functionality and introduce my own functionality.
The flow diagram for this process is- MKLocalSearch -> MKMapItem -> Determine altitude using coordinates from MKMapItem -> Initialise MapItemGeoSpatial.
I can create an override init() for the above class, but this will require me to initialise the altitude property, which is not specified for this initialiser. Initialising altitude by specifying a dummy variable (eg. 0) overcomes this issue, but appears to be a poor workaround. Making altitude optional is another workaround, but this is not a direction I wish to take.
I'm aware that MKMapItem inherits from NSObject and I'm curious if this relation has an influence on the above observation. I would like to-
Understand the root cause behind this issue and
Determine if subclassing MKMapItem is a viable solution to the problem mentioned at the start of this post
Hello, how can I turn this standard map view into a Satellite map view?
Thanks
// MapView.swift
// Grindelwald View
//
// Created by Roman Indermühle on 15.04.22.
//
import MapKit
import SwiftUI
struct City: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct MapView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 46.62407, longitude: 8.03434), span: MKCoordinateSpan(latitudeDelta: 0.17, longitudeDelta: 0.17))
let annotations = [
City(name: "Burglauenen", coordinate: CLLocationCoordinate2D(latitude: 46.63649, longitude: 7.97512)),
City(name: "Stalden", coordinate: CLLocationCoordinate2D(latitude: 46.63937, longitude: 7.97216)),
City(name: "Stalden2", coordinate: CLLocationCoordinate2D(latitude: 46.63873, longitude: 7.96684))
]
var body: some View {
Map(coordinateRegion: $region, annotationItems: annotations) {
MapMarker(coordinate: $0.coordinate)
}
}
}
struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}
Post not yet marked as solved
In Maps there is a cycling option available in certain cities, however MKDirectionsTransportType only has automobile, walking, transit and any.
Is there a way to get cycling routes for say London using mapKit?
Post not yet marked as solved
Guys how is it possible to set a map type like hybrid, satellite etc on the following code? Thanks in advance!
import MapKit
struct MapView: View {
@State private var region: MKCoordinateRegion = {
var mapCoordinates = CLLocationCoordinate2D(latitude: 6.600286, longitude: 16.4377599)
var mapZoomLevel = MKCoordinateSpan(latitudeDelta: 70.0, longitudeDelta: 70.0)
var mapRegion = MKCoordinateRegion(center: mapCoordinates, span: mapZoomLevel)
return mapRegion
} ()
let locations: [NationalParkLocation] = Bundle.main.decode("locations.json")
var body: some View {
Map(coordinateRegion: $region, annotationItems: locations, annotationContent: { item in
MapAnnotation(coordinate: item.location) {
Image("logo")
.resizable()
.scaledToFit()
.frame(width: 32, height: 32, alignment: .center)
}
})
}
}
Post not yet marked as solved
Hi All,
I am trying to implement Alternate Routes using Mapkit in Swift. I am able to get the alternate route details but unable to handle the alternate route selection and drawing the polyline for the selected route.
Can someone help me in achieving this some sample code snippet or references?
Thanks in advance.
Post not yet marked as solved
I want to see all the public transport stations on my MKMapView.
With the following code I get train stations on the map:
mapView.pointOfInterestFilter = MKPointOfInterestFilter(including: [.publicTransport])
But the bus stops are missing.
If I use the Apple Maps app and chose Transit as the map, the bus stops are available there.
How can I get the bus stops in my app using MKMapView?
Post not yet marked as solved
I have an MKRoute which I get from an MKDirections.Request. I want to change the coordinates of some points of the route. However, the polyline property of the route is get only. How can I do that?
Post not yet marked as solved
With a Safari extension I add a link to certain websites to open the Maps app with coordinates found on the website.
In the content script I detect clicks on my added link and forward the message to the background script with browser.runtime.sendMessage({ coordinates: "some coordinates I found on the website" }).
The background script receives this message in its listener function and forwards the message to the extension handler like so
browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
browser.runtime.sendNativeMessage( { message: request.coordinates }, function(response) {
});
}
The extension handler receives the message in its func beginRequest(with context: NSExtensionContext) function as expected.
In this function I convert the coordinates I receive to a valid CLLocationCoordinate2D object.
However, if I want to use the following code inside the beginRequest function to open the Maps app, it does not work on iOS. The same code works fine with a macOS Safari extension.
MKMapItem(placemark: MKPlacemark(coordinate: CLLocationCoordinate2D(latitude: 50.1234, longitude: 8.1234))).openInMaps()
Post not yet marked as solved
Failed to parse font key token
is displayed at console.
It doesn't particularly cause crashes, UI bugs, etc., but it is a concern.
This is occurred when I zoom on SwiftUI Map.
Part of code
struct MapView: View {
var body: some View {
Map(coordinateRegion: $viewModel.region,
showsUserLocation: true,
annotationItems: viewModel.pins,
annotationContent: { item in
MapAnnotation(coordinate: item.coordinate, anchorPoint: CGPoint(x: 0.5, y: 0.5), content: {
pinButton(pin: item)
})
})
.ignoresSafeArea()
}
}
My project is here.
Post not yet marked as solved
I have a simple map made with "pure" SwiftUI. There is a search bar to search a place and when I click the "Go" button it shows the instructions of how to go that place from a particular location. It shows it below the map, on the "Enter a destination" field. What I want to do is, I want these instructions to be clickable. When I click each of the instructions it should zoom in that particular place where the instruction takes place. Right now it's only a list of text. Is it possible to do it without using UIViewRepresentable? And how can I do it?
I tried with
.onTapGesture {
region.span = MKCoordinateSpan(latitudeDelta: region.span.latitudeDelta/2, longitudeDelta: region.span.longitudeDelta/2)
}
but it zooms in the same location on every instruction I click.
ContentView
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct RouteSteps: Identifiable {
let id = UUID()
let step: String
}
struct ContentView: View {
@State private var searchBar: String = ""
@State private var home = CLLocationCoordinate2D(latitude: 39.90068, longitude: 32.86081)
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 39.90068, longitude: 32.86081), span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
@State var routeSteps: [RouteSteps] = [RouteSteps(step: "Enter a destination")]
@State var annotations = [Location(name: "Ankara", coordinate: CLLocationCoordinate2D(latitude: 39.90068, longitude: 32.86081))]
var body: some View {
VStack{
HStack {
TextField("", text: $searchBar)
Button("Go") {
findNewLocation()
}
.frame(width: 35, height: 35)
.foregroundColor(Color.white)
.background(Color.blue)
.cornerRadius(5)
}.textFieldStyle(.roundedBorder).colorInvert()
Map(coordinateRegion: $region, annotationItems: annotations){ item in
MapMarker(coordinate: item.coordinate)
}.frame(width: 400, height: 300)
List(routeSteps) { r in
Text(r.step)
}
route function in ContentView
func findNewLocation(){
let searchResult = searchBar
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(searchResult, completionHandler:
{(placemarks, error) -> Void in
if((error) != nil){
print("error at geocode")
}
if let placemark = placemarks?.first {
let coordinates : CLLocationCoordinate2D = placemark.location!.coordinate
region = MKCoordinateRegion(center: coordinates, span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
annotations.append(Location(name: placemark.name!, coordinate: coordinates))
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: home, addressDictionary: nil))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: coordinates, addressDictionary: nil))
request.requestsAlternateRoutes = false
request.transportType = .automobile
let directions = MKDirections(request: request)
directions.calculate(completionHandler: { response, error in
for route in (response?.routes)! {
self.routeSteps = []
for step in route.steps {
self.routeSteps.append(RouteSteps(step: step.instructions))
}
}
})
}
})
}