Pass the url from the marker into the controller - swift

I'm doing the app for viewing IP cameras and want to add cameras to the map so you can click on the desired marker and go to see the desired camera. I have a map and PlayerViewController which reproduce a webcam.
Now each marker only transmits the first stream of the webcam. Help me. How to make different webcam worked?
ViewController
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var moscow: [(name: String, URLs:String, img:String, latitude: Double, longitude: Double)] =
[("cam1", "http://example/1.m3u8", "1.jpg", 55.753989, 37.620235),
("cam2", "http://example/2.m3u8", "2.jpg", 55.741308, 37.653914),
("cam3","http://example/3.m3u8","3.jpg", 55.742468, 37.629292)]
override func viewDidLoad() {
super.viewDidLoad()
var latitudes = moscow.map({ $0.latitude })
var longitudes = moscow.map({ $0.longitude })
var annotations = moscow.map({ $0.name })
for i in 0...2 {
let coordinate = CLLocationCoordinate2DMake(latitudes[i], longitudes[i])
let span = MKCoordinateSpanMake(0.003, 0.003)
let region = MKCoordinateRegionMake(coordinate, span)
mapView.setRegion(region, animated:true)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = annotations[i]
self.mapView.addAnnotation(annotation)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
print(#function)
}
// Called when the annotation was added
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.animatesDrop = true
pinView?.canShowCallout = true
pinView?.isDraggable = true
pinView?.pinColor = .purple
let rightButton: AnyObject! = UIButton(type: UIButtonType.detailDisclosure)
pinView?.rightCalloutAccessoryView = rightButton as? UIView
} else {
pinView?.annotation = annotation
}
return pinView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
print(#function)
if control == view.rightCalloutAccessoryView {
performSegue(withIdentifier: "toTheMoon", sender: self)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toTheMoon" {
let controller = segue.destination as! PlayerViewController
var urlll = moscow.map({ $0.URLs })
for i in 0...2 {
controller.webcamURL = urlll[i] // only first cam play
}
}
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if newState == MKAnnotationViewDragState.ending {
let droppedAt = view.annotation?.coordinate
print(droppedAt)
}
}
}
PlayerViewController
import UIKit
import AVFoundation
import AVKit
class PlayerViewController: AVPlayerViewController {
var webcamURL: String!
var webcamTitle: String!
override func viewDidLoad() {
super.viewDidLoad()
self.title = webcamTitle
let url = URL(string: webcamURL)
player = AVPlayer(url: url!)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
player!.play()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.player!.pause()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
player = nil
}
}

First of All MKAnnotation is a Protocol so you can implement this protocol in your model class, lets say "Camera"
import UIKit
import MapKit
class Camera: NSObject, MKAnnotation {
var name: String = ""
var urlString :String = ""
var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0)
var imageName : String = ""
init(name:String,camUrl:String,imageNamed:String,latitude:CLLocationDegrees,longitude:CLLocationDegrees) {
super.init()
self.name = name
self.urlString = camUrl
self.imageName = imageNamed
guard latitude != 0 && longitude != 0 else
{
return
}
guard latitude.isNaN || longitude.isNaN else
{
return
}
self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
// Title and subtitle for use by selection UI.
public var title: String? {
get{
return self.name
}
}
}
Then you can reduce your ViewController code like this
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
var moscow: [Camera] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.moscow = [Camera(name: "cam1", camUrl: "http://example/1.m3u8", imageNamed: "1.jpg", latitude: 55.753989, longitude: 37.620235),
Camera(name: "cam2", camUrl: "http://example/2.m3u8", imageNamed: "2.jpg", latitude: 55.741308, longitude: 37.653914),
Camera(name: "cam3", camUrl: "http://example/3.m3u8", imageNamed: "3.jpg", latitude: 55.742468, longitude: 37.629292)]
self.mapView.addAnnotations(self.moscow)
self.mapView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController : MKMapViewDelegate
{
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
print(#function)
}
// Called when the annotation was added
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.animatesDrop = true
pinView?.canShowCallout = true
pinView?.isDraggable = true
pinView?.pinColor = .purple
let rightButton: AnyObject! = UIButton(type: UIButtonType.detailDisclosure)
pinView?.rightCalloutAccessoryView = rightButton as? UIView
} else {
pinView?.annotation = annotation
}
return pinView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
print(#function)
let camera = view.annotation as! Camera
if control == view.rightCalloutAccessoryView {
performSegue(withIdentifier: "toTheMoon", sender: camera)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toTheMoon" {
let controller = segue.destination as! PlayerViewController
controller.webcamURL = (sender as! Camera).urlString
controller.webcamTitle = (sender as! Camera).name
}
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
if newState == MKAnnotationViewDragState.ending {
let droppedAt = view.annotation?.coordinate
print(droppedAt)
}
}
}
Hope this helps

Related

Error showing customs anotation in maps swift

I'm trying to show some custom anotation I can see the custom picture in its place but the text disappears and reapear every time I zoom in or out. I've checked several similar question but I don't know how to apply to my code. So please help!
import UIKit
import MapKit
class LocalizacionViewController: UIViewController,MKMapViewDelegate {
var evento: Evento?
#IBOutlet weak var actIndicator: UIActivityIndicatorView!
#IBOutlet weak var contenedorView: UIView!
#IBOutlet weak var mkMapa: MKMapView!
override func viewDidLoad() {
mkMapa.delegate = self
super.viewDidLoad()
evento = eventos.eventoPulsado()
}
override func viewWillAppear(_ animated: Bool) {
contenedorView.layer.borderWidth = 2
contenedorView.aplicarFondoDegradado()
contenedorView.layer.borderColor = UIColor.white.cgColor
contenedorView.layer.cornerRadius = 10
customPin()
let initialLocation = CLLocationCoordinate2D(latitude: (evento!.lat)!, longitude: (evento!.long)!)
mkMapa.setCenter(initialLocation, animated: true)
let region = MKCoordinateRegion(center: initialLocation,latitudinalMeters: 2000,longitudinalMeters: 2000)
mkMapa.setRegion(region, animated: true)
}
func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
actIndicator.isHidden = true
actIndicator.stopAnimating()
}
func customPin(){
let addAnotation = MKPointAnnotation()
addAnotation.title = evento!.nombre
addAnotation.coordinate = CLLocationCoordinate2D(latitude: evento!.lat!, longitude: evento!.long!)
self.mkMapa.addAnnotation(addAnotation)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "custom")
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "custom")
} else {
annotationView?.annotation = annotation
}
annotationView?.image = UIImage(named:"bars.png" )
return annotationView
}
}

How can I use the generic Apple Maps pins for locations in MapKit, rather than having to use my own images as pins?

In my application, I have stored coordinates in FireBase and am displaying those coordinates on a Map View in the code below. The current location of the user is also being harnessed. I would like the locations I have stored in FireBase to be represented by the generic Apple Maps pins, but I do not know how to get the app to work unless I use custom images as pins instead. Also, the generic "blue dot" of the user displayed on the map to represent the current location will not appear for me. In different projects in which the locations are stored in-app rather than in FireBase, the generic pins and blue dot appear just as I would like them to. How can I fix this?
I have tried changing bits and pieces of the code, but I am rather new to Swift and the programming world in general, and cannot find a solution.
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBAction func mapSwitch(_ sender: UISwitch) {
if (sender.isOn == true) {
mapView.mapType = MKMapType.standard
}
else {
mapView.mapType = MKMapType.hybrid
}
}
var tappedAnnotation : MKAnnotation?
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let view = mapView.dequeueReusableAnnotationView(withIdentifier: "Annotation") {
view.annotation = annotation
view.image = UIImage(named: "pin")
return view
} else {
let view = MKAnnotationView(annotation: annotation, reuseIdentifier: "Annotation")
view.image = UIImage(named: "pin")
view.isEnabled = true
view.canShowCallout = true
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
return view
}
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
tappedAnnotation = view.annotation
performSegue(withIdentifier: "showAnnotationDetails", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showAnnotationDetails", let dest = segue.destination as? AnnotationDetails {
dest.annotation = tappedAnnotation
}
}
func createAnnotations ( _ annotations : [String:[String:Any]] ) {
mapView.removeAnnotations(mapView.annotations)
for (_,values) in annotations {
if let latDouble = values["latitude"] as? Double, let longDouble = values["longitude"] as? Double {
let lat = CLLocationDegrees( latDouble )
let long = CLLocationDegrees( longDouble )
let coord = CLLocationCoordinate2D(latitude: lat, longitude: long)
let annotation = MKPointAnnotation()
annotation.coordinate = coord
annotation.title = values["name"] as? String ?? ""
annotation.subtitle = values["info"] as? String ?? ""
mapView.addAnnotation(annotation)
}
}
}
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
mapView.delegate = self
mapView.mapType = MKMapType.standard
let ref = Database.database().reference()
ref.child("annotations").observe(.value) { snapshot in
print(snapshot)
if let annotations = snapshot.value as? [String:[String:Any]] {
self.createAnnotations(annotations)
} else {
print("Data received not formatted as expected")
}
}
}
Use MKPinAnnotationView instead of MKAnnotationView
Set mapView.showsUserLocation = true to show user location (blue dot)

Make mutliple pin annotations buttons to segue to an other view controller (swift 3)

I have two pin annotations on my map. I created a info button to perform the segue. But the button appears only on one annotation. Can anyone help me please? For the annotations I created a function that I put into the viewdidload method.
Here`s the code:
import UIKit
import MapKit
class MapVC: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
meinkartenPunkt1()
meinkartenPunkt2()
locManager = CLLocationManager()
locManager.requestWhenInUseAuthorization()
// Do any additional setup after loading the view.
mapView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
func mapView(_ mapView: MKMapView,didUpdate userLocation: MKUserLocation){
mapView.region.center=userLocation.coordinate
mapView.showAnnotations(mapView.annotations, animated: true)
}
func meinkartenPunkt1() {
let breite: CLLocationDegrees = 8.737653
let länge: CLLocationDegrees = 47.504333
let Koordinaten = CLLocationCoordinate2DMake(länge, breite)
let Span = MKCoordinateSpanMake(0.01, 0.01)
let Region = MKCoordinateRegionMake(Koordinaten, Span)
mapView.setRegion(Region, animated: true)
let Stecknadel = MKPointAnnotation()
Stecknadel.coordinate = Koordinaten
Stecknadel.title = "Heiligberg"
mapView.addAnnotation(Stecknadel)
}
func meinkartenPunkt2() {
let breite: CLLocationDegrees = 8.734345
let länge: CLLocationDegrees = 47.508456
let Koordinaten = CLLocationCoordinate2DMake(länge, breite)
let Span = MKCoordinateSpanMake(0.01, 0.01)
let Region = MKCoordinateRegionMake(Koordinaten, Span)
mapView.setRegion(Region, animated: true)
let Stecknadel = MKPointAnnotation()
Stecknadel.coordinate = Koordinaten
Stecknadel.title = "Kanti Rychenberg"
mapView.addAnnotation(Stecknadel)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
if annotation is MKUserLocation {return nil}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
let calloutButton = UIButton(type: .detailDisclosure)
pinView!.rightCalloutAccessoryView = calloutButton
pinView!.sizeToFit()
}
else {
pinView!.annotation = annotation
}
return pinView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
performSegue(withIdentifier: "bookDetails", sender: self)
}
}
}
When looking at your source code, I cannot directly see an answer, however I see an immediate problem. You do some important setup on the pinView, while it is nil. To be honest, this code certainly crashes, if it is ever reached:
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
Luckily for you, pinView never is nil however, as the mapView creates the pinView successfully. What you probably want to do, is to set the calloutButton, if it is not set. So instead of if pinView == nil you write:
if pinView?.rightCalloutAccessoryView == nil {
// Initialize the rightCalloutAccessoryView here
}
Tip: In general you should avoid force unwraps with ! as it leads to crashes. Try to use optional chaining with ? instead.

ViewForAnnotation not Called in Swift 3

I want to open a new viewcontroller when i click the PinAnnotation. But ViewForannotation is not calling when i click, But It is showing a pop up message when i click on Pin. Don't know what is happening. Here is my Code:
import UIKit
import MapKit
class Pin: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
var key: String
var title: String?
var age: String?
var category: String?
var color: MKPinAnnotationColor = MKPinAnnotationColor.purple
var subtitle: String?
init(key: String, name: String , age: String , category: String , color: MKPinAnnotationColor) {
self.coordinate = CLLocationCoordinate2D(latitude: 0, longitude: 0)
self.key = key
self.title = name
self.color = color
self.subtitle = age
self.category = category
//print("keyy: ", key)
//print("title: ", name)
}
}
This is my MapViewControllerClass:
import UIKit
import GeoFire
import MapKit
import Firebase
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, UIAlertViewDelegate {
//#IBOutlet weak var sidebarButton: UIBarButtonItem!
#IBOutlet weak var mapView: MKMapView!
//#IBOutlet weak var chatbarButton: UIBarButtonItem!
/* ---> NEW MAP-IT <--- */
let locationManager = CLLocationManager()
let imagePicker = UIImagePickerController()
var regionQuery: GFRegionQuery?
var foundQuery: GFCircleQuery?
var annotations: Dictionary<String, Pin> = Dictionary(minimumCapacity: 8)
var lastExchangeKeyFound: String?
var lastExchangeLocationFound: CLLocation?
var location: CLLocation!
// var location = CLLocation(latitude: 37.33233141, longitude: -122.0312186)
//let location = CLLocation(latitude: 37.33209999, longitude: -122.0326666)
var circle: MKCircle!
var index = 0
var val1Lat: Double!
var val2Lat: Double!
var val1Long: Double!
var val2Long: Double!
var flag = false
var userName = ""
var age = ""
var category = ""
var uid = ""
override func viewDidLoad() {
super.viewDidLoad()
uid = DataService.ds.currentUserID
self.mapView.delegate = self
// locationManager.requestAlwaysAuthorization()
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) || (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) {
print("Authorized")
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
} else {
print("Application is not authorized to use location services")
//- TODO: Unauthorized, requests permissions again and makes recursive call
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if manager.location?.coordinate != nil {
if flag == true {
if (location.coordinate.latitude != manager.location?.coordinate.latitude) || (location.coordinate.longitude != manager.location?.coordinate.longitude) {
location = manager.location!//.coordinate
print("lat: \(location.coordinate.latitude)")
print("long: \(location.coordinate.longitude)")
animateMap(location: location)
let key = DataService.ds.currentUserID
geofire!.setLocation(location, forKey: key)
}
} else {
print("Else:LocationManag")
location = manager.location!
print("lat: \(location.coordinate.latitude)")
print("long: \(location.coordinate.longitude)")
animateMap(location: location)
flag = true
let key = DataService.ds.currentUserID
geofire!.setLocation(location, forKey: key)
}
}
}
override func viewDidAppear(_ animated: Bool) {
print("DidAppear")
self.mapView.userLocation.addObserver(self, forKeyPath: "location", options: NSKeyValueObservingOptions(), context: nil)
}
override func viewDidDisappear(_ animated: Bool) {
print("DidDisAppear")
locationManager.stopUpdatingLocation()
self.mapView.userLocation.removeObserver(self, forKeyPath: "location", context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print("In observer")
if (self.mapView.showsUserLocation) && (self.mapView.userLocation.location) != nil
{
let span = MKCoordinateSpanMake(0.0125, 0.0125)
let region = MKCoordinateRegion(center: self.mapView.userLocation.location!.coordinate /*location.coordinate*/, span: span)
self.mapView.setRegion(region, animated: true)
if foundQuery == nil {
print("FoundQuery nill")
foundQuery = geofire?.query(at: /*location*/self.mapView.userLocation.location, withRadius: 0.2)
foundQuery!.observe(GFEventType.keyEntered, with: { (key: String?, location:CLLocation?) -> Void in
//print("here")
DataService.ds.userRef.child(key!).observeSingleEvent(of: .value, with: { (snapshot) in
if let userDictionary = snapshot.value as? Dictionary<String , AnyObject>
{
self.userName = userDictionary["firstName"] as! String
self.age = userDictionary["age"] as! String
self.category = userDictionary["category"] as! String
}
self.lastExchangeKeyFound = key
self.lastExchangeLocationFound = location
if key != DataService.ds.currentUserID {
let annotation = Pin(key: key!, name: self.userName , age: self.age , category: self.category , color: MKPinAnnotationColor.green)
annotation.coordinate = (location?.coordinate)!
annotation.title = self.userName + " - " + self.age
annotation.subtitle = self.category
// if self.category == "Trainer"{
// annotation.color = MKPinAnnotationColor.green
// }else{
// annotation.color = MKPinAnnotationColor.purple
// }
self.mapView.addAnnotation(annotation)
self.annotations[key!] = annotation
}
})
self.foundQuery?.observe(.keyExited, with: { (key, location) in
if key != DataService.ds.currentUserID {
if self.annotations[key!] != nil {
self.mapView.removeAnnotation(self.annotations[key!]!)
self.annotations[key!] = nil
}
}
})
})
}
else
{
foundQuery?.center = self.mapView.userLocation.location
}
}
}
//Click Event For Annotation:
// func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!,
// calloutAccessoryControlTapped control: UIControl!) {
//
// if control == view.rightCalloutAccessoryView {
// print("Disclosure Pressed! \(view.annotation?.subtitle)")
// }
//
// }
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
print("inPin1")
if annotation is Pin {
print("inPin2")
let pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
pinAnnotationView.pinColor = .purple
pinAnnotationView.isDraggable = true
pinAnnotationView.canShowCallout = true
pinAnnotationView.animatesDrop = true
let deleteButton = UIButton.init(type: UIButtonType.custom) as UIButton
// let deleteButton = UIButton.withType(UIButtonType.custom) as UIButton
deleteButton.frame.size.width = 44
deleteButton.frame.size.height = 44
deleteButton.backgroundColor = UIColor.red
deleteButton.setImage(UIImage(named: "xbutton"), for: .normal)
pinAnnotationView.leftCalloutAccessoryView = deleteButton
return pinAnnotationView
}
return nil
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
if let annotation = view.annotation as? Pin {
mapView.removeAnnotation(annotation)
}
}
// func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView {
// var annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "loc")
// annotationView.canShowCallout = true
// annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
// return annotationView
// }
//
// func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
// mapView.deselectAnnotation(view.annotation, animated: true)
// var controller = self.storyboard!.instantiateViewController(withIdentifier: "DetailsPopover")
// controller.annotation! = view.annotation
// self.popover = UIPopoverController(contentViewController: controller)
// self.popover.delegate = self
// self.popover.presentPopoverFromRect(view.frame, inView: view.superview!, permittedArrowDirections: .Any, animated: true)
// }
// func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
// print("helloooo")
// self.performSegue(withIdentifier: "detailView", sender: view)
// }
// func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// // simple and inefficient example
// let annotationView = MKPinAnnotationView()
// if category == "Trainer"{
// annotationView.pinTintColor = .purple
// }else{
// annotationView.pinTintColor = .green
// }
//
//
//
// return annotationView
// }
func animateMap(location: CLLocation)
{
// print("animate Map")
let region = MKCoordinateRegionMakeWithDistance(location.coordinate, 1000, 1000)
mapView.setRegion(region, animated: true)
addRadiusCircle(location: location)
}
func addRadiusCircle(location: CLLocation)
{
//print("Add Radius")
//self.mapView.delegate = self
if circle != nil
{
self.mapView.remove(circle)
}
circle = MKCircle(center: location.coordinate, radius: 200 as CLLocationDistance)
self.mapView.add(circle)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
{
if overlay is MKCircle
{
let circle = MKCircleRenderer(overlay: overlay)
circle.strokeColor = UIColor.red
circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
circle.lineWidth = 1
return circle
}
else {
let temp = MKOverlayRenderer()
return temp
}
}
}
I am Using Geofire to get the nearby users in a particular radius and then pin that users. Please help.
You are saying:
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView!
That will certainly never be called. In Swift 3, the correct signature is:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
All you have to do is consult the documentation:
https://developer.apple.com/reference/mapkit/mkmapviewdelegate/1452045-mapview
In case anyone else was having the same issue while still using the correct signature, ensure you've set your mapView delegate:
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}

Swift- segue between views with map annotation button

I relatively new to programming and need help switching between views by tapping a button in a mapView annotated pin.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
//REF
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var bottompnl: UIImageView!
#IBAction func mysticsbtn(sender: AnyObject) {
}
#IBAction func bondibtn(sender: AnyObject) {
}
//MAP
let locationManager = CLLocationManager()
//Annotation
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
let identifier = "beach"
if annotation is Beach {
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
let btn = UIButton(type: .DetailDisclosure)
annotationView!.rightCalloutAccessoryView = btn
} else {
annotationView!.annotation = annotation
}
return annotationView
self.performSegueWithIdentifier("mysticssegue", sender: nil)
}
return nil
}
override func viewDidLoad() {
super.viewDidLoad()
let annotations = getMapAnnotations()
// Add mappoints to Map
mapView.addAnnotations(annotations)
mapView.delegate = self
//MAP
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
//MAKES THE DOT
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MAP: Location Delegates Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let centre = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: centre, span: MKCoordinateSpan(latitudeDelta: 3, longitudeDelta: 3))
self.mapView.setRegion(region, animated: true)
self.locationManager.startUpdatingLocation()
}
//TO FIND ERROS
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Erros: " + error.localizedDescription)
}
//MARK:- Annotations
func getMapAnnotations() -> [Beach] {
var annotations:Array = [Beach]()
//load plist file
var beaches: NSArray?
if let path = NSBundle.mainBundle().pathForResource("beaches", ofType: "plist") {
beaches = NSArray(contentsOfFile: path)
}
if let items = beaches {
for item in items {
let lat = item.valueForKey("lat") as! Double
let long = item.valueForKey("long")as! Double
let annotation = Beach(latitude: lat, longitude: long)
annotation.title = item.valueForKey("title") as? String
annotations.append(annotation)
}
}
return annotations
}
//END
}
It looks like you're returning from the function mapView before calling performSegueWithIdentifier.
return annotationView
self.performSegueWithIdentifier("mysticssegue", sender: nil)
Try reversing the order of these two lines. I also noticed that you have some #IBAction methods that have no code in them.