SwiftUI Polyline not updating to follow user as they move - ios

I have spent a lot of time researching this question and have tried a few approaches but none have worked for me. Any help would be greatly appreciated by this Swift noob.
To gain more MapKit experience, I am trying to show the user their path with a polyline on the map that follows their movements, similar to run apps that track the user. I can track the user just fine but I cannot show a live map with a Polyline that updates as they move. When closing the map and coming back to it the polyline is updated with the missing coordinates. ** I suspect the answer to my problem relates to this :) **
Image showing the map after it loads and the user moves away from the Polyline. Closing the map and reopening redraws the missing points of the polyline
LocationViewModel.swift
var locationArray: [CLLocation] = []
var coordArray: [CLLocationCoordinate2D] = []
(...)
var coordinates2D:[CLLocationCoordinate2D] {
var coordArray = [CLLocationCoordinate2D]()
for c in locationArray {
let lat = c.coordinate.latitude
let long = c.coordinate.longitude
let x = CLLocationCoordinate2D(latitude: lat, longitude: long)
coordArray.append(x)
}
return coordArray
}
(...)
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for newLocation in locations {
let howRecent = newLocation.timestamp.timeIntervalSinceNow
guard newLocation.horizontalAccuracy < 20 && abs(howRecent) < 10 else { continue }
speeds.append(contentsOf: locationArray.map{$0.speed}) //append all new speed updates to the array
altitude.append(contentsOf: locationArray.map{$0.altitude}) //append all new speed updates to the array
locationArray.append(newLocation)
}
SecondMap.swift
import Foundation
import SwiftUI
import MapKit
struct SecondMap: UIViewRepresentable {
typealias UIViewType = MKMapView
#EnvironmentObject var model: LocationsModel
#State var regionZoom = LocationService.sharedLocInstance.locationManager.location?.coordinate
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.showsUserLocation = true
mapView.userTrackingMode = .followWithHeading
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
// uiView.removeAnnotation(uiView.annotations)
// uiView.showAnnotations(self.locations, animated: true)
if regionZoom != nil {
let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
let region = MKCoordinateRegion(center: regionZoom!, span: span)
uiView.setRegion(region, animated: true)
}
let polyline = MKPolyline(coordinates: model.coordinates2D, count: model.coordinates2D.count)
uiView.removeOverlay(polyline)
uiView.addOverlay(polyline)
uiView.delegate = context.coordinator
}
static func dismantleUIView(_ uiView: MKMapView, coordinator: ()) {
// uiView.removeAnnotation(uiView.annotations)
}
//MARK: - Create Coordinator Class
func makeCoordinator() -> Coordinator {
return Coordinator()
}
class Coordinator: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// If the annotation is the user dot then return nil
if annotation is MKUserLocation {
return nil
}
// Create an annotation view
let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "business")
annotationView.canShowCallout = false
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.isHidden = true
return annotationView
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let routePolyline = overlay as? MKPolyline {
let renderer = MKPolylineRenderer(polyline: routePolyline)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 7
return renderer
}
return MKOverlayRenderer()
}
}
}
TrackerDetailCard
import SwiftUI
import MapKit
struct TrackerDetailView: View {
#EnvironmentObject var model: LocationsModel
#State var isMapShowing = false
// #State var regionZoom = LocationService.sharedLocInstance.locationManager.location?.coordinate
var body: some View {
NavigationView {
if !isMapShowing {
VStack(alignment: .leading) {
HStack{
Text("Map info and stuff")
Button {
self.isMapShowing = true
} label: {
Text("Launch Map")
.font(.system(size: 12))
.foregroundColor(.gray)
}
.buttonStyle(NEUMORPHISM_BUTTON())
} // HSTACK END
HStack {
Button {
LocationService.sharedLocInstance.locationManager.startUpdatingLocation()
} label: {
Text("Record runs")
.font(.system(size: 12))
.foregroundColor(.gray)
}
.buttonStyle(NEUMORPHISM_BUTTON_SQ())
Button {
LocationService.sharedLocInstance.locationManager.stopUpdatingLocation()
} label: {
Text("End recording")
.font(.system(size: 12))
.foregroundColor(.gray)
}
.buttonStyle(NEUMORPHISM_BUTTON_SQ())
Button {
print("button tapped")
} label: {
Text("Something")
.font(.system(size: 12))
.foregroundColor(.gray)
}
.buttonStyle(NEUMORPHISM_BUTTON_SQ())
}
VStack{
Text("Average Speed: \(model.avgSpeed)")
Text("Top Speed: \(model.topSpeed)")
// Text("Top Speed: \(model.altitude)")
}
Spacer()
} // VSTACK END
.navigationBarHidden(true)
}
else{
ZStack(alignment: .top){
// show map
SecondMap()
.ignoresSafeArea()
ZStack{
Rectangle()
.foregroundColor(.white)
.cornerRadius(5)
.frame(height: 48)
HStack{
Image(systemName: "location")
Spacer()
Button("Back to home") {
self.isMapShowing = false
}
}.padding()
}.padding()
}
}
} // BODY END
}
}

Related

How to zoom in and out with buttons on MGLMapView using Swift?

I'm a newbie and I am trying to make a simple map project. I want to zoom in and out with buttons on the map but it's not working. I already tried using MKMapView but I can't change MGLMapView to MKMapView.
I tried to set a mglMapCamera variable in MapView and use it in ContentView but it didn't work either.
Also in MapView on this line: mglMapView = mapView
I'm getting this warning:
Modifying state during view update, this will cause undefined behavior.
MapView
#State public var mglMapView = MGLMapView()
#State public var mglMapCamera = MGLMapCamera()
func makeUIView(context: Context) -> MGLMapView {
// read the key from property list
let mapTilerKey = getMapTilerkey()
validateKey(mapTilerKey)
// Build the style url
let styleURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=\(mapTilerKey)")
// create the mapview
let mapView = MGLMapView(frame: .zero, styleURL: styleURL)
mglMapView = mapView
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.logoView.isHidden = true
mapView.setCenter(
CLLocationCoordinate2D(latitude: 47.127757, longitude: 8.579139),
zoomLevel: 10,
animated: true)
mapView.layoutMargins = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
// use the coordinator only if you need
// to respond to the map events
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ uiView: MGLMapView, context: Context) {}
func makeCoordinator() -> MapView.Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, MGLMapViewDelegate {
var control: MapView
init(_ control: MapView) {
self.control = control
}
func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
// write your custom code which will be executed
// after map has been loaded
}
}
ContentView
var mapView = MapView()
#State var currentZoom:CGFloat = 10.0
func ZoominOutMap(level:CGFloat){
let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 47.127757, longitude: 8.579139), fromEyeCoordinate: self.mapView.mglMapView.camera.centerCoordinate, eyeAltitude: 10)
self.mapView.mglMapView.setCamera(camera, animated: true)
}
Buttons in ContentView
VStack {
Button("+") {
currentZoom = currentZoom + 1
self.ZoominOutMap(level: currentZoom)
}
.frame(width: 30, height: 30)
.foregroundColor(Color.white)
.background(Color.gray)
.clipShape(Circle())
Button("-") {
currentZoom = currentZoom - 1
self.ZoominOutMap(level: currentZoom)
}
.frame(width: 30, height: 30)
.foregroundColor(Color.white)
.background(Color.gray)
.clipShape(Circle())
}
You can call a cameraUpdate for the same cameraPosition but zoom+=1 or -=1 to zoom in or out.
Then call animateCamera with that update and it should zoom in just fine.

Presenting a view in Swift with Objective-C code?

I usually work with Obj-C but I have 2 .swift files that I have imported into my project, what I am looking to do is launch one of the files, from one of my Obj-C viewController files (which subsequently is attached to a xib)
-(IBAction)gotoCompass:(id)sender {
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen //or .overFullScreen for transparency
self.present(vc, animated: true, completion: nil)
}
That is the action I want to use, the .swift file names are
ContentView.swift & CompassHeading.swift
I would like to present one of them using the IBAction above, but currently it shows
'Use of undeclared identifier 'let'
I have imported the Bridging-Header file and the top of the .m file is
FirstViewController.m
#interface FirstViewController ()
#end
#implementation FirstViewController
Edit -
Here is the contents of ContentView.swift
import Foundation
import SwiftUI
struct Marker: Hashable {
let degrees: Double
let label: String
init(degrees: Double, label: String = "") {
self.degrees = degrees
self.label = label
}
func degreeText() -> String {
return String(format: "%.0f", self.degrees)
}
static func markers() -> [Marker] {
return [
Marker(degrees: 0, label: "N"),
Marker(degrees: 30),
Marker(degrees: 60),
Marker(degrees: 90, label: "E"),
Marker(degrees: 120),
Marker(degrees: 150),
Marker(degrees: 180, label: "S"),
Marker(degrees: 210),
Marker(degrees: 240),
Marker(degrees: 270, label: "W"),
Marker(degrees: 300),
Marker(degrees: 330)
]
}
}
struct CompassMarkerView: View {
let marker: Marker
let compassDegress: Double
var body: some View {
VStack {
Text(marker.degreeText())
.fontWeight(.light)
.rotationEffect(self.textAngle())
Capsule()
.frame(width: self.capsuleWidth(),
height: self.capsuleHeight())
.foregroundColor(self.capsuleColor())
Text(marker.label)
.fontWeight(.bold)
.rotationEffect(self.textAngle())
.padding(.bottom, 180)
}.rotationEffect(Angle(degrees: marker.degrees))
}
private func capsuleWidth() -> CGFloat {
return self.marker.degrees == 0 ? 7 : 3
}
private func capsuleHeight() -> CGFloat {
return self.marker.degrees == 0 ? 45 : 30
}
private func capsuleColor() -> Color {
return self.marker.degrees == 0 ? .red : .gray
}
private func textAngle() -> Angle {
return Angle(degrees: -self.compassDegress - self.marker.degrees)
}
}
struct ContentView : View {
#ObservedObject var compassHeading = CompassHeading()
var body: some View {
VStack {
Capsule()
.frame(width: 5,
height: 50)
ZStack {
ForEach(Marker.markers(), id: \.self) { marker in
CompassMarkerView(marker: marker,
compassDegress: self.compassHeading.degrees)
}
}
.frame(width: 300,
height: 300)
.rotationEffect(Angle(degrees: self.compassHeading.degrees))
.statusBar(hidden: true)
}
}
}
Also there is a CompassHeading.swift file;
import Foundation
import Combine
import CoreLocation
class CompassHeading: NSObject, ObservableObject, CLLocationManagerDelegate {
var objectWillChange = PassthroughSubject<Void, Never>()
var degrees: Double = .zero {
didSet {
objectWillChange.send()
}
}
private let locationManager: CLLocationManager
override init() {
self.locationManager = CLLocationManager()
super.init()
self.locationManager.delegate = self
self.setup()
}
private func setup() {
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.headingAvailable() {
self.locationManager.startUpdatingLocation()
self.locationManager.startUpdatingHeading()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
self.degrees = -1 * newHeading.magneticHeading
}
}

SwiftUI Can't Capture Image of MapView

I have a SwiftUI app that includes a map. I want to capture an image of the map and display that image as a SwiftUI Image on another view. I have been unable to find any documentation on this. I tried two approaches at capturing and neither of them work. See the extensions below.
This is a simplified example:
ContentView:
struct ContentView: View {
#State private var showDetail: Bool = false
#State private var thumbImage: Image = Image(systemName: "gear")
var body: some View {
VStack {
Text("This is the ContentView")
if showDetail {
DetailMapView(thumbImage: $thumbImage)
}
if !showDetail {
Image(systemName: "gear")
.resizable()
.frame(width: 200, height: 200)
}
Button(action: {
self.showDetail.toggle()
}) {
Text("Tap for Map")
}
}
}
}
And the MapView:
struct DetailMapView: UIViewRepresentable {
typealias UIViewType = MKMapView
#Binding var thumbImage: Image
class Coordinator: NSObject, MKMapViewDelegate {
var parent: DetailMapView
init(_ parent: DetailMapView) {
self.parent = parent
}
}//coordinator
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.showsUserLocation = true
mapView.delegate = context.coordinator
// this does not work - it crashes
// let s = mapView.pb_takeSnapshot()
// self.thumbImage = Image(uiImage: s)
//this does not work either - it produces lots of console complaints
let t = mapView.screenshot
DispatchQueue.main.async {
self.thumbImage = Image(uiImage: t)
}
return mapView
}
}
extension UIView {
func pb_takeSnapshot() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
extension UIView {
var screenshot: UIImage{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return UIImage() }
self.layer.render(in: context)
guard let screenShot = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage() };
UIGraphicsEndImageContext()
return screenShot
}
}
Console output for the screenshot version:
[VKDefault] TextureAtlasPage: Atlas page destroyed with outstanding references.: Assertion with expression - _textureRefs == 0 : Failed in file - /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1606.34.10.29.27/src/TextureAtlas.cpp line - 604
[VKDefault] TextureAtlasPage: Atlas page destroyed with outstanding references.: Assertion with expression - _textureRefs == 0 : Failed in file - /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1606.34.10.29.27/src/TextureAtlas.cpp line - 604
Any guidance would be appreciated. Xcode 11.4 (11E146)
For others:
This works for me - forget the extensions above. The key is to use
mapViewDidFinishRenderingMap and that function needs to be inside the Coordinator class.
func mapViewDidFinishRenderingMap(_ mapView: MKMapView, fullyRendered: Bool) {
//setup whatever region you want to see :mapView.setRegion(region, animated: true)
let render = UIGraphicsImageRenderer(size: mapView.bounds.size)
let ratio = mapView.bounds.size.height / mapView.bounds.size.width
let img = render.image { (ctx) in
mapView.drawHierarchy(in: CGRect(x: 100, y: 100, width: 300, height: 300 * ratio), afterScreenUpdates: true)
}
DispatchQueue.main.async {
self.parent.thumbImage = Image(uiImage: img)
}
}
i would recommend to use MKMapSnapshotter from Apple because if you render the map manually yourself you always get the Apple symbol with it...which you "normally" do not want ;)

How to remove two annotation on the same spot?

I would like to have only one annotation on a spot with title and subtitle. I am facing the problem that i get two annotations. The default annotation and may custom annotation. I want only the custom annotation.
The main methods to look after are probably: addAnnotation and the delegate methods.
Here is picture of the problem:
enter image description here
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController {
let locationManager = CLLocationManager()
let regionInMeters: Double = 10000
let localMap: MKMapView = {
let map = MKMapView()
map.translatesAutoresizingMaskIntoConstraints = false
return map
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
checkLocationService()
addAnnotations()
}
private func setupUI() {
setupConstraints()
}
}
// MARK: constraints
extension ViewController {
private func setupConstraints() {
view.addSubview(localMap)
NSLayoutConstraint.activate([
localMap.topAnchor.constraint(equalTo: view.topAnchor),
localMap.leadingAnchor.constraint(equalTo: view.leadingAnchor),
localMap.trailingAnchor.constraint(equalTo: view.trailingAnchor),
localMap.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
}
extension ViewController: CLLocationManagerDelegate, MKMapViewDelegate {
// checking location service is available
private func checkLocationService() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
}
}
private func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
print("Yesss")
localMap.showsUserLocation = true
centerViewOnUserLocation()
//locationManager.startUpdatingLocation()
break
case .denied:
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
break
case .restricted:
break
case .authorizedAlways:
break
#unknown default:
fatalError()
}
}
private func setupLocationManager() {
localMap.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
private func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
localMap.setRegion(region, animated: true)
}
}
// Delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
localMap.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
// MARK: annotation
private func addAnnotations() {
let restaurantAnnotation = MKPointAnnotation()
restaurantAnnotation.title = "FOOD BROTHER"
restaurantAnnotation.subtitle = "Best burger in town"
restaurantAnnotation.coordinate = CLLocationCoordinate2D(latitude: 52.37085, longitude: 9.732710)
localMap.addAnnotation(restaurantAnnotation)
}
// https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwijvYel7NTlAhVMjqQKHWeiChAQFjAAegQICBAB&url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F49020023%2Fmapkit-annotations-disappearing&usg=AOvVaw2G13fjRVWs3b49cLQTjG_I
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "annotationView"
if annotation is MKUserLocation {
return nil
}
var view = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if #available(iOS 11.0, *) {
if view == nil {
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
view?.displayPriority = .required
} else {
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
}
let pinImage = UIImage(named: "restaurantsIcon.png")
let size = CGSize(width: 50, height: 50)
UIGraphicsBeginImageContext(size)
pinImage!.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
view?.image = resizedImage
view?.annotation = annotation
view?.canShowCallout = true
return view
}
}
I found another approach to tackle that problem.
Here it is:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "annotationView"
if annotation is MKUserLocation {
return nil
}
var view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
view.glyphImage = UIImage(named: "restaurantsIcon")
view.markerTintColor = .systemPink
view.displayPriority = .required
view.annotation = annotation
view.canShowCallout = true
return view
}

How to remove the annotation for my Location in Swift? I want only a pulsating dot

I am facing one problems. I want to show only the annotations which I really added. So in my case i want to get my pulsating dot for my location back. Not a annotation. I hope somebody can help me.
I think the main methods to get a look into are the delegate methods and the addAnnotations method.
Here is a picture of my problem:
double annotations and annotation my current location
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController {
let locationManager = CLLocationManager()
let regionInMeters: Double = 10000
let localMap: MKMapView = {
let map = MKMapView()
map.translatesAutoresizingMaskIntoConstraints = false
return map
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
checkLocationService()
addAnnotations()
}
private func setupUI() {
setupConstraints()
}
}
// MARK: constraints
extension ViewController {
private func setupConstraints() {
view.addSubview(localMap)
NSLayoutConstraint.activate([
localMap.topAnchor.constraint(equalTo: view.topAnchor),
localMap.leadingAnchor.constraint(equalTo: view.leadingAnchor),
localMap.trailingAnchor.constraint(equalTo: view.trailingAnchor),
localMap.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
}
}
extension ViewController: CLLocationManagerDelegate, MKMapViewDelegate {
// checking location service is available
private func checkLocationService() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
}
}
private func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
print("Yesss")
localMap.showsUserLocation = true
centerViewOnUserLocation()
//locationManager.startUpdatingLocation()
break
case .denied:
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
break
case .restricted:
break
case .authorizedAlways:
break
#unknown default:
fatalError()
}
}
private func setupLocationManager() {
localMap.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
private func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
localMap.setRegion(region, animated: true)
}
}
// Delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
localMap.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
// MARK: annotation
private func addAnnotations() {
let restaurantAnnotation = MKPointAnnotation()
restaurantAnnotation.title = "FOOD BROTHER"
restaurantAnnotation.subtitle = "Best burger in town"
restaurantAnnotation.coordinate = CLLocationCoordinate2D(latitude: 52.37085, longitude: 9.732710)
localMap.addAnnotation(restaurantAnnotation)
}
// https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=2ahUKEwijvYel7NTlAhVMjqQKHWeiChAQFjAAegQICBAB&url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F49020023%2Fmapkit-annotations-disappearing&usg=AOvVaw2G13fjRVWs3b49cLQTjG_I
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "annotationView"
var view = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if #available(iOS 11.0, *) {
if view == nil {
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
view?.displayPriority = .required
} else {
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
}
let pinImage = UIImage(named: "restaurantsIcon.png")
let size = CGSize(width: 50, height: 50)
UIGraphicsBeginImageContext(size)
pinImage!.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
view?.image = resizedImage
view?.annotation = annotation
view?.canShowCallout = true
return view
}
}
Add the following code to delegate method.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// Add 3 line code
if annotation is MKUserLocation {
return nil
}
...
}

Resources