How to remove two annotation on the same spot? - ios

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
}

Related

How to show in which side user turn phone, if I show user location using MKMapView

I want to show into which side the user turns the phone, like on MapView, and can't understand how to do that, I have tried to use these options, but they can't help me:
mapView.showsUserLocation = true
mapView.isRotateEnabled = true
mapView.isPitchEnabled = true
mapView.showsCompass = true
mapView.userTrackingMode = .follow
Update this line:
mapView.userTrackingMode = .followWithHeading
The problem was solved by this answer and the help of Asteroid, appreciated your support.
My code:
import UIKit
import MapKit
import CoreLocation
class MapScreen: UIViewController, MKMapViewDelegate {
let locationManager = CLLocationManager()
var location: CLLocation!
lazy var mapView: MKMapView = {
let map = MKMapView()
map.delegate = self
return map
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(mapView)
mapView.frame = view.frame
initUserLocation()
}
var headingImageView: UIImageView?
var userHeading: CLLocationDirection?
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
if views.last?.annotation is MKUserLocation {
addHeadingView(toAnnotationView: views.last!)
}
}
func addHeadingView(toAnnotationView annotationView: MKAnnotationView) {
if headingImageView == nil {
let image = UIImage(named: "iconU")
headingImageView = UIImageView(image: image)
headingImageView!.frame = CGRect(x: (annotationView.frame.size.width - image!.size.width)/2, y: (annotationView.frame.size.height - image!.size.height)/2, width: image!.size.width, height: image!.size.height)
annotationView.insertSubview(headingImageView!, at: 0)
headingImageView!.isHidden = true
}
}
}
extension MapScreen: CLLocationManagerDelegate {
func initUserLocation() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.startUpdatingHeading()
mapView.showsUserLocation = true
// mapView.userTrackingMode = .followWithHeading
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.location = locations.last as CLLocation?
}
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
if newHeading.headingAccuracy < 0 { return }
let heading = newHeading.trueHeading > 0 ? newHeading.trueHeading : newHeading.magneticHeading
userHeading = heading
updateHeadingRotation()
}
func updateHeadingRotation() {
if let heading = userHeading,
let headingImageView = headingImageView {
headingImageView.isHidden = false
let rotation = CGFloat(heading/180 * Double.pi)
headingImageView.transform = CGAffineTransform(rotationAngle: rotation)
}
}
}

Xcode and iOS: debugQuickLookObject() showing MKMapView

In Xcode if you hover over a variable of type CLLocation and klick on the eye symbol, Xcode shows that location on a map.
To find bugs in data that is not mine, I wanted to have the same behaviour for objects of type MKPolyline.
First the test code:
import XCTest
import MapKit
class PolylineQuicklookTests: XCTestCase {
func testPolylineQuicklook() throws {
let wilhelma = CLLocationCoordinate2D(latitude: 48.804513, longitude: 9.206237)
let fernsehturm = CLLocationCoordinate2D(latitude: 48.755890, longitude: 9.190290)
let path = [wilhelma, fernsehturm]
let polyline = MKPolyline(coordinates: path, count: path.count)
print("set breakpoint here and test polyline Quicklook")
}
}
extend MKPolyline to invoke Quicklook:
extension MKPolyline {
#objc public func debugQuickLookObject() -> Any? {
//return "MKPolyline \(self.coordinates.count)"
quickLookMapVC = QuickLookMapVC(overlays: [self], annotations: [])
let view = quickLookMapVC?.view
return view
}
}
// hold reference:
fileprivate var quickLookMapVC: QuickLookMapVC?
And a simple implementation:
fileprivate class QuickLookMapVC: UIViewController {
var overlays: [MKOverlay] = []
var annotations: [MKAnnotation] = []
var mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
var testLabel = UILabel()
init() {
super.init(nibName: nil, bundle: nil)
}
convenience init(overlays: [MKOverlay], annotations: [MKAnnotation]) {
self.init()
print("QuickLookMapVC init \(overlays.count), \(annotations.count)")
self.overlays = overlays
self.annotations = annotations
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
print("QuickLookMapVC start viewDidLoad")
/*
testLabel.text = "Test"
testLabel.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.testLabel)
let constraints = [
testLabel.topAnchor.constraint(equalTo: view.topAnchor),
testLabel.leftAnchor.constraint(equalTo: view.leftAnchor),
view.bottomAnchor.constraint(equalTo: testLabel.bottomAnchor),
view.rightAnchor.constraint(equalTo: testLabel.rightAnchor)
]
NSLayoutConstraint.activate(constraints)
*/
mapView.delegate = self
mapView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(self.mapView)
let constraints = [
mapView.topAnchor.constraint(equalTo: view.topAnchor),
mapView.leftAnchor.constraint(equalTo: view.leftAnchor),
view.bottomAnchor.constraint(equalTo: mapView.bottomAnchor),
view.rightAnchor.constraint(equalTo: mapView.rightAnchor)
]
NSLayoutConstraint.activate(constraints)
mapView.mapType = .standard
mapView.addOverlays(overlays)
mapView.addAnnotations(annotations)
let stuttgart = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 48.775846, longitude: 9.182932),
latitudinalMeters: 5000, longitudinalMeters: 5000)
mapView.region = stuttgart
/*
if annotations.count > 0 {
mapView.showAnnotations(annotations, animated: true)
}
if let firstOverlay = overlays.first {
let mapRect = firstOverlay.boundingMapRect
print(mapRect)
mapView.visibleMapRect = mapRect
}
*/
}
}
extension QuickLookMapVC: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let polyline = overlay as? MKPolyline {
print("rendererFor polyline")
// for real applications do reuse instead of creating a new one each time:
let polylineRenderer = MKPolylineRenderer(polyline: polyline)
polylineRenderer.strokeColor = .red
// lineWith: defaults to 0, which is MKRoadWidthAtZoomScale(currentZoomScale)
return polylineRenderer
}
if let polygon = overlay as? MKPolygon {
print("rendererFor polygon")
let polygonrenderer = MKPolygonRenderer(polygon: polygon)
polygonrenderer.fillColor = .red
return polygonrenderer
}
print("rendererFor overlay")
return MKOverlayRenderer(overlay: overlay)
}
}
I'd expect so see at least a map.
What I'm seeing is an MKMapView with the usual Apple copyright symbols but no map.
The copyright symbols let me assume that the mapView is at least sized correctly and rendered.
Console shows
QuickLookMapVC init 1, 0
QuickLookMapVC start viewDidLoad
rendererFor polyline
When I replace MKMapView with a UILabel, the label is shown correctly.
This lets me assume that the invocation and the UIViewController parts work fine and only MKMapView is a problem.
What can I do that my code actually shows map data and a polyline?

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
}
...
}

How do I overlay a circle at a set location using mapkit and swift

I am having trouble trying to figure out how to display a transparent circle or rectangle at a desired location unique from the users location. Im a beginner with mapkit so thanks in advance.
class FirstViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate
{
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()//
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Errors: " + error.localizedDescription)
}
}
This has been updated to support Swift 4.2. Comments are provided to explain several of the choices I made.
import UIKit
import MapKit
class Map: UIViewController {
var mapView = MKMapView()
func setup() {
// Assign delegate here. Can call the circle at startup,
// or at a later point using the method below.
// Includes <# #> syntax to simplify code completion.
mapView.delegate = self
showCircle(coordinate: <#CLLocationCoordinate2D#>,
radius: <#CLLocationDistance#>)
}
// Radius is measured in meters
func showCircle(coordinate: CLLocationCoordinate2D,
radius: CLLocationDistance) {
let circle = MKCircle(center: coordinate,
radius: radius)
mapView.addOverlay(circle)
}
}
extension Map: MKMapViewDelegate {
func mapView(_ mapView: MKMapView,
rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// If you want to include other shapes, then this check is needed.
// If you only want circles, then remove it.
if let circleOverlay = overlay as? MKCircle {
let circleRenderer = MKCircleRenderer(overlay: circleOverlay)
circleRenderer.fillColor = .black
circleRenderer.alpha = 0.1
return circleRenderer
}
// If other shapes are required, handle them here
return <#Another overlay type#>
}
}
I have achieve the following using the following
import UIKit
import MapKit
class MapVC: UIViewController,CLLocationManagerDelegate {
var locationManager = CLLocationManager()
#IBOutlet weak var mapView : MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check for Location Services
if (CLLocationManager.locationServicesEnabled()) {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
//Zoom to user location
if let userLocation = locationManager.location?.coordinate {
let viewRegion = MKCoordinateRegion(center: userLocation, latitudinalMeters: 200, longitudinalMeters: 200)
let region = CLCircularRegion(center: userLocation, radius: 5000, identifier: "geofence")
mapView.addOverlay(MKCircle(center: userLocation, radius: 200))
mapView.setRegion(viewRegion, animated: false)
}
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
}
extension MapVC : MKMapViewDelegate{
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
var circleRenderer = MKCircleRenderer()
if let overlay = overlay as? MKCircle {
circleRenderer = MKCircleRenderer(circle: overlay)
circleRenderer.fillColor = UIColor.green
circleRenderer.strokeColor = .black
circleRenderer.alpha = 0.5
}
return circleRenderer
}
}
My Output:

swift custom map class

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.

Resources