I do a app with MapKit and I want the user can select an annotation (clic on) and then open a new view controller.
I do it with the method :
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
performSegue(withIdentifier: "showClic", sender: nil)
}
But this code open the VC when there a cluster of annotation.
And I want to do when there is a cluster of annotation a zoom with the camera and open the VC only when only one annotation is selected.
func fitMapViewToAnnotaionList(annotations: [MKPointAnnotation], userLocation: CLLocationCoordinate2D) -> Void {
let mapEdgePadding = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
var zoomRect:MKMapRect = MKMapRectNull
for index in 0..<annotations.count {
let annotation = annotations[index]
let aPoint:MKMapPoint = MKMapPointForCoordinate(annotation.coordinate)
let rect:MKMapRect = MKMapRectMake(aPoint.x, aPoint.y, 0.1, 0.1)
if MKMapRectIsNull(zoomRect) {
zoomRect = rect
} else {
zoomRect = MKMapRectUnion(zoomRect, rect)
}
}
let aPoint:MKMapPoint = MKMapPointForCoordinate(userLocation)
let rect:MKMapRect = MKMapRectMake(aPoint.x, aPoint.y, 0.1, 0.1)
if MKMapRectIsNull(zoomRect) {
zoomRect = rect
} else {
zoomRect = MKMapRectUnion(zoomRect, rect)
}
mapView.setVisibleMapRect(zoomRect, edgePadding: mapEdgePadding, animated: true)
}
Related
I'm trying to update some map components while dragging an annotations like highlighting a specific MGLPolygon and panning the map if the annotation is already dragged near the edge. I will use the later for this problem.
I tried the code https://docs.mapbox.com/ios/maps/examples/draggable-views/ and added some lines. Here's the exact copy with my changes.
import Mapbox
// Example view controller
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView = MGLMapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.styleURL = MGLStyle.streetsStyleURL
mapView.tintColor = .darkGray
mapView.zoomLevel = 1
mapView.delegate = self
view.addSubview(mapView)
// Specify coordinates for our annotations.
let coordinates = [
CLLocationCoordinate2D(latitude: 0, longitude: -70),
CLLocationCoordinate2D(latitude: 0, longitude: -35),
CLLocationCoordinate2D(latitude: 0, longitude: 0),
CLLocationCoordinate2D(latitude: 0, longitude: 35),
CLLocationCoordinate2D(latitude: 0, longitude: 70)
]
// Fill an array with point annotations and add it to the map.
var pointAnnotations = [MGLPointAnnotation]()
for coordinate in coordinates {
let point = MGLPointAnnotation()
point.coordinate = coordinate
point.title = "To drag this annotation, first tap and hold."
pointAnnotations.append(point)
}
mapView.addAnnotations(pointAnnotations)
}
// MARK: - MGLMapViewDelegate methods
// This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
// This example is only concerned with point annotations.
guard annotation is MGLPointAnnotation else {
return nil
}
// For better performance, always try to reuse existing annotations. To use multiple different annotation views, change the reuse identifier for each.
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "draggablePoint") {
return annotationView
} else {
let dav = DraggableAnnotationView(reuseIdentifier: "draggablePoint", size: 50)
dav.mapView = mapView
return dav
}
}
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
return true
}
}
// MGLAnnotationView subclass
class DraggableAnnotationView: MGLAnnotationView {
var mapView: MGLMapView!
var screen: CGRect!
var mapBounds: CGRect!
init(reuseIdentifier: String, size: CGFloat) {
super.init(reuseIdentifier: reuseIdentifier)
// `isDraggable` is a property of MGLAnnotationView, disabled by default.
isDraggable = true
// This property prevents the annotation from changing size when the map is tilted.
scalesWithViewingDistance = false
// Begin setting up the view.
frame = CGRect(x: 0, y: 0, width: size, height: size)
backgroundColor = .darkGray
// Use CALayer’s corner radius to turn this view into a circle.
layer.cornerRadius = size / 2
layer.borderWidth = 1
layer.borderColor = UIColor.white.cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.1
screen = UIScreen.main.bounds
mapBounds = CGRect(
x: screen.origin.x + 20,
y: screen.origin.y + 20,
width: screen.size.width - 40,
height: screen.size.height - 40)
}
// These two initializers are forced upon us by Swift.
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// Custom handler for changes in the annotation’s drag state.
override func setDragState(_ dragState: MGLAnnotationViewDragState, animated: Bool) {
super.setDragState(dragState, animated: animated)
switch dragState {
case .starting:
print("Starting", terminator: "")
startDragging()
case .dragging:
let pointCoordinate = self.mapView.convert(center, toCoordinateFrom: nil)
if mapBounds.contains(center) {
DispatchQueue.main.async {
self.mapView.setCenter(pointCoordinate, animated: true)
}
}
print(".", terminator: "")
case .ending, .canceling:
print("Ending")
endDragging()
case .none:
break
#unknown default:
fatalError("Unknown drag state")
}
}
// When the user interacts with an annotation, animate opacity and scale changes.
func startDragging() {
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
self.layer.opacity = 0.8
self.transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
}, completion: nil)
// Initialize haptic feedback generator and give the user a light thud.
if #available(iOS 10.0, *) {
let hapticFeedback = UIImpactFeedbackGenerator(style: .light)
hapticFeedback.impactOccurred()
}
}
func endDragging() {
transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
self.layer.opacity = 1
self.transform = CGAffineTransform.identity.scaledBy(x: 1, y: 1)
}, completion: nil)
// Give the user more haptic feedback when they drop the annotation.
if #available(iOS 10.0, *) {
let hapticFeedback = UIImpactFeedbackGenerator(style: .light)
hapticFeedback.impactOccurred()
}
}
}
Everytime the self.mapView.setCenter(pointCoordinate, animated: true) gets called, the annotations goes back and forth to its original position.
Here is the code explaining the Adonis's solution. Essentially add a pan gesture to a custom annotation's view and update the coords as and when the annotation is panned.
class CustomDraggableAnnotaionView: MGLAnnotationView {
required init(
reuseIdentifier: String?,
image: UIImage?,
annotation: CustomMapGLAnnotaion
) {
super.init(reuseIdentifier: reuseIdentifier)
setupDraggableAnnotations()
self.layer.zPosition = 10
}
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Draggable annotation handlers
private func setupDraggableAnnotations() {
addDraggableAnnotationGestureRecognizers()
}
private func addDraggableAnnotationGestureRecognizers() {
let panGesture = UIPanGestureRecognizer(
target: self,
action: #selector(self.draggedView(_:))
)
let tapGesture = UITapGestureRecognizer(
target: self,
action: #selector(self.tappedAnnotation(_:))
)
self.isUserInteractionEnabled = true
self.addGestureRecognizer(panGesture)
self.addGestureRecognizer(tapGesture)
for recognizer in self.gestureRecognizers! where recognizer is UITapGestureRecognizer {
tapGesture.require(toFail: recognizer)
}
for recognizer in self.gestureRecognizers! where recognizer is UIPanGestureRecognizer {
panGesture.require(toFail: recognizer)
}
}
#objc func draggedView(_ sender: UIPanGestureRecognizer) {
annotationObject?.draggable!.isCurrentlyDragging = true
let point = sender.location(in: MapManager.shared.mapView)
let coordinates = MapManager.shared.mapView.convert(
point,
toCoordinateFrom: MapManager.shared.mapView
)
annotationObject?.coordinate = coordinates
if sender.state == .ended {
// endDragging()
} else if sender.state == .began {
// startDragging()
annotationObject?.draggable!.handler.didStartDragging()
} else {
//
}
}
}
I'm trying to create simple custom map annotations on Mapbox iOS (5.5.0) by implementing MGLMapViewDelegate protocol. Annotations are actually added to the map, but they are invisible. I can predict its coordinate and open its callout, so, I know it's there.
I have even tried copying the exact codes given on Mapbox examples to get the same result. Can it be a lack of some framework elements?
My code:
class MainViewController: UIViewController, MGLMapViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Set the map’s size, style, center coordinate, zoom level, and tint color.
let mapView = MGLMapView(frame: view.bounds)
let coordinates = CLLocationCoordinate2D(latitude: 40.4561, longitude: 49.7263)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.styleURL = MGLStyle.darkStyleURL(withVersion: 9)
mapView.setCenter(coordinates, zoomLevel: 15, animated: false)
//mapView.userTrackingMode = .followWithHeading
//mapView.showsUserHeadingIndicator = true
view.addSubview(mapView)
mapView.delegate = self
let marker = MGLPointAnnotation()
marker.coordinate = coordinates
marker.title = "Area 51"
marker.subtitle = "There is no way in!"
mapView.addAnnotation(marker)
}
// Use the default marker. See also: our view annotation or custom marker examples.
func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
guard annotation is MGLPointAnnotation else {
return nil
}
let annotationAvailable = isAnnotationAvailable(annotation)
let reuseIdentifier = "\(annotationAvailable)"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if (annotationView == nil) {
annotationView = MGLAnnotationView()
annotationView = CustomAnnotationView(reuseIdentifier: reuseIdentifier)
annotationView!.bounds = CGRect(x: 0, y: 0, width: 40, height: 40)
if (!annotationAvailable) {
annotationView!.backgroundColor = UIColor(displayP3Red: 255, green: 0, blue: 0, alpha: 1)
}
else {
annotationView!.backgroundColor = UIColor(displayP3Red: 0, green: 255, blue: 0, alpha: 1)
}
}
return annotationView
}
// Allow callout view to appear when an annotation is tapped.
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
return true
}
func isAnnotationAvailable(_ annotation: MGLAnnotation) -> Bool {
return false
}
}
class CustomAnnotationView: MGLAnnotationView {
override func layoutSubviews() {
super.layoutSubviews()
// Use CALayer’s corner radius to turn this view into a circle.
layer.cornerRadius = bounds.width / 2
layer.borderWidth = 2
layer.borderColor = UIColor.white.cgColor
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Animate the border width in/out, creating an iris effect.
let animation = CABasicAnimation(keyPath: "borderWidth")
animation.duration = 0.1
layer.borderWidth = selected ? bounds.width / 4 : 2
layer.add(animation, forKey: "borderWidth")
}
}
The result:
Mapbox Screenshot
When the animation is executing , i try to click the moving annotationView ,but cannnot be selected, the mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) hasn't been called
func addMoveAnimation() {
guard let ano = annotation as? Annotation else {
return
}
animator = UIViewPropertyAnimator.init(duration: 10, curve: .linear, animations: {
ano.coordinate = CLLocationCoordinate2D(latitude: 32.449819, longitude: 112.292726)
})
animator?.startAnimation()
animator?.addCompletion({ (position) in
print(position.des,"coor:", ano.coordinate)
})
}
i try to add a UITapGestureRecognizer for the annotationView, and it really works, but then quickly changed to be deseleted, and the mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) also be called
#objc func handleGes() {
print("tap ges click")
removeAnimation()
let currentFrame = (layer.presentation() as! CALayer).frame
layer.removeAllAnimations()
let point = CGPoint.init(x: currentFrame.midX, y: currentFrame.midY)
let coor = mapView?.convert(point, toCoordinateFrom: mapView)
guard let ano = annotation as? Annotation, let coordinate = coor else {
return
}
ano.coordinate = coordinate
print(ano.coordinate)
mapView?.selectAnnotation(ano, animated: false)
}
I want to do animation like "when scroll collection view cell the annotation pin goes Up/Down at the end of scrolling. But how to do animation like annotation pin goes Up when start scrolling and annotation pin goes Down when scrolling end in collection view
//code --> For Scrolling
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
if scrollView == collectionView {
NSLog("page collection %d",Int(scrollView.contentOffset.x/scrollView.frame.size.width))
self.UpdateMapAnotationPin(Int(scrollView.contentOffset.x/scrollView.frame.size.width))
}
}
// -->When Update Pin
func UpdateMapAnotationPin(vIndex : Int) {
if self.mapAnnotations.count != 0 {
let info = self.mapAnnotations[vIndex]
let aView = map.viewForAnnotation(info)
info.imageName = "ic_map_pin1"
info.tagPin = vIndex
aView?.image = UIImage(named: info.imageName)
if aView != nil {
self.animationWithView(aView!)
}
}
}
// --> For animation
func animationWithView(mkView : MKAnnotationView) {
let point:MKMapPoint = MKMapPointForCoordinate(mkView.annotation!.coordinate);
let endFrame:CGRect = mkView.frame;
mkView.frame = CGRectMake(mkView.frame.origin.x, mkView.frame.origin.y - 20, mkView.frame.size.width, mkView.frame.size.height);
let delay = 0.03
UIView.animateWithDuration(0.5, delay: delay, options: UIViewAnimationOptions.CurveLinear, animations:{() in
mkView.frame = endFrame
}, completion:{(Bool) in
UIView.animateWithDuration(0.05, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations:{() in
mkView.transform = CGAffineTransformMakeScale(1.0, 1.0) }, completion: {(Bool) in
UIView.animateWithDuration(0.3, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations:{() in
mkView.transform = CGAffineTransformIdentity
}, completion: nil)
})
})
}
I think you want to animated like AirBnb app annotations.
You have to select the pin by calling it's viewforAnimation method
Steps
1.Make annotation using by assigning the custom id like this
class GridAnnotation: NSObject ,MKAnnotation{
var title: String?
var coordinate: CLLocationCoordinate2D
var info: String
var index: String
init(title: String, coordinate: CLLocationCoordinate2D, info: String,index: String) {
self.title = title
self.coordinate = coordinate
self.info = info
self.index = index
}
}
override func viewDidLoad() {
super.viewDidLoad()
let annotationStart = GridAnnotationStart(title: "", coordinate: firstLocation.coordinate, info: "\(zoneCreateModal.id)",index: "\(0)")
self.mapVw.addAnnotation(annotationSta
rt)
}
2.Get all annotations
let arrAllAnnotations = self.mapVw.annotations.filter { $0 !== self.mapVw.userLocation }
for someAnnotation in annotationsToRemove {
let strId = "Your current id"
if someAnnotation.isKind(of: AnnotationModal.self) {
let annotaion = someAnnotation as! AnnotationModal
if annotaion.info == strId {
//Call view for animation
self.mapVw.selectAnnotation(someAnnotation, animated: true)
self.mapVw.view(for: someAnnotation)
}
}
}
5.Set type of new selected annoatation in viewForAnnotation
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if (annotation.isKind(of: MKUserLocation.self)) {
return nil
}
if annotation.isKind(of: GridAnnotationZoomModal.self) {
let anView = MKAnnotationView(annotation: annotation, reuseIdentifier: "landingPoints")
let annotationInfo = annotation as! GridAnnotationZoomModal
imgView.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
if anView.isSelected == true {
imgView.image = UIImage(named: "Your selected image name")
}else{
imgView.image = UIImage(named: "Your image not selected name")
}
anView.isDraggable = false
anView.isEnabled = true
anView.isUserInteractionEnabled = true
anView.tag = Int(annotationInfo.index)!
anView.addSubview(imgView)
anView.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
anView.centerOffset = CGPoint(x: 0,y: -15)
return anView
}
return nil
}
I am learning Swift and want to create a subclass of MKMapKit to encapsulate some specific functionality, like checking distance between two points and creating custom annotations and separate all the map code into one class.
I have created a class:
class GameMapViewController: MKMapView, MKMapViewDelegate{...}
I initiate the class in code in the main view controller (and adding it as a subview to a view on the storyboard so I can control where it is more easily):
gameMap = GameMapViewController(container: mapViewHolder)
which sets everything up ok and all works EXCEPT for when I want to trigger a segue from a custom annotation:
func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {...}
The didSelectAnnotationView gets called when I tap on an annotation callout but nothing has the method performSegueWithIdentifier that I am looking for, that all the solutions to similar questions suggest I should be using....
(I have tried putting a MapKit View onto the storyboard and changing its class to use GameMapViewController but none of the init functions get fired)
I am guessing its something to with how I am initialising my custom class?
MainViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
....
// Create the game map
gameMap = GameMapViewController(container: mapViewHolder)
mapViewHolder.addSubview(gameMap)
...
}
GameMapViewController.swift:
import UIKit
import MapKit
class GameMapViewController: MKMapView, MKMapViewDelegate{
var spanQuestion:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var spanAnswer:MKCoordinateSpan = MKCoordinateSpanMake(180, 180)
var hasUserCityLocationGuess: Bool = false
var containingView: UIView
override init(){
println ("GameMapViewController init")
containingView = UIView()
super.init(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
self.delegate=self
var latDeltaAnswer:CLLocationDegrees = 50
var lngDeltaAnswer:CLLocationDegrees = 50
spanAnswer = MKCoordinateSpanMake(latDeltaAnswer, lngDeltaAnswer)
var latDeltaQuestion:CLLocationDegrees = 180
var lngDeltaQuestion:CLLocationDegrees = 180
spanQuestion = MKCoordinateSpanMake(latDeltaQuestion, lngDeltaQuestion)
}
required init(coder aDecoder: NSCoder) {
containingView = UIView()
super.init(coder: aDecoder)
self.delegate = nil
println ("GameMapViewController init with decoder")
}
convenience init(container: UIView) {
println ("GameMapViewController convenience")
self.init()
self.delegate = self
containingView = container
}
func mapViewDidFinishLoadingMap(mapView: MKMapView!) {
println("mapViewDidFinishLoadingMap")
}
func mapViewWillStartLoadingMap(mapView: MKMapView!) {
self.frame = CGRect (x: 0, y: 0, width: containingView.frame.width, height: containingView.frame.height)
self.contentMode = UIViewContentMode.ScaleAspectFill
superview?.sizeToFit()
var guessPlaceRecognizer = UILongPressGestureRecognizer(target: self, action: "guessPlace:")
guessPlaceRecognizer.minimumPressDuration = 1.0
mapView.addGestureRecognizer(guessPlaceRecognizer)
mapView.mapType = MKMapType.Satellite
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKCircle {
var circleRenderer = MKCircleRenderer(overlay: overlay)
circleRenderer.strokeColor = UIColor.redColor()
circleRenderer.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
circleRenderer.lineWidth = 1
//userOverlayCircleRender = circleRenderer
return circleRenderer
} else {
return nil
}
}
func guessPlace(gestureRecognizer:UIGestureRecognizer){
let guessPlaceFirst = NSUserDefaults.standardUserDefaults().boolForKey("guess_place_preference")
if guessPlaceFirst {
var touchPoint = gestureRecognizer.locationInView(self)
var newCoord:CLLocationCoordinate2D = self.convertPoint(touchPoint, toCoordinateFromView: self)
var userAnnotation = UserPointAnnotation()
userAnnotation.coordinate = newCoord
self.addAnnotation(userAnnotation)
var getLat: CLLocationDegrees = newCoord.latitude
var getLon: CLLocationDegrees = newCoord.longitude
var circleCenter: CLLocation = CLLocation(latitude: getLat, longitude: getLon)
addRadiusCircle(circleCenter)
hasUserCityLocationGuess = true
}
}
func showCity() {
let location = CLLocationCoordinate2D(latitude: (currentCity["latitude"]! as CLLocationDegrees), longitude: (currentCity["longitude"]! as CLLocationDegrees))
let region:MKCoordinateRegion = MKCoordinateRegionMake(location, self.spanAnswer)
let city: String = currentCity["city"]! as String
let conditions: String = currentCity["description"] as String
let country: String = currentCity["country"]! as String
let address = "\(city), \(country)"
let cityAnnotation = CityPointAnnotation()
cityAnnotation.title = address
cityAnnotation.subtitle = "\(conditions)"
cityAnnotation.coordinate = location
self.setRegion(region, animated: true)
self.addAnnotation(cityAnnotation)
self.selectAnnotation(cityAnnotation, animated: true)
}
func cityInfoClick(sender:UIButton){
//sender.performSegueWithIdentifier("segueCityWebView")
}
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
// Handle any custom annotations.
if annotation is CityPointAnnotation {
// Try to dequeue an existing pin view first.
let reuseId = "CityPointAnnotationView"
var annotationView = self.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
annotationView.image = UIImage(named: "marker.png")
annotationView.rightCalloutAccessoryView = UIButton.buttonWithType(.InfoDark) as UIButton
annotationView.canShowCallout = true
return annotationView;
} else {
annotationView.annotation = annotation
}
return annotationView
}
return nil;
}
func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) {
println("didSelectAnnotationView")
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
println("calloutAccessoryControlTapped1")
///////////////////
// I want to do a segue here
// but nothing has the method performSegueWithIdentifier (self, mapView, control....)
///////////////////
}
func resetMap(){
self.removeAnnotations(self.annotations)
self.removeOverlays(self.overlays)
var region:MKCoordinateRegion = MKCoordinateRegionMake(self.centerCoordinate, spanQuestion)
self.setRegion(region, animated: true)
hasUserCityLocationGuess = false
}
func addRadiusCircle(location: CLLocation){
var radius = NSUserDefaults.standardUserDefaults().doubleForKey("guess_place_radius") as CLLocationDistance
var circle = MKCircle(centerCoordinate: location.coordinate, radius: radius )
self.removeOverlays(self.overlays)
self.addOverlay(circle)
}
func doGeoCode( cityObject:PFObject ) -> Bool {
....
}
func userCityLocationGuess(userGuessTemp:Int)->NSDictionary {
....
}
}
It's because you're confusing views and view controllers. You have a view (subclass of MKMapView, but you're naming it and trying to use it as a controller. It is also doings the job of a controller.
So, you should really have a view controller which owns and configures a map view (plain MKMapView), and then it can interact with segues.