1

On Swift 1.2 : I'd like to add a button to my annotations on the map. First tap on pin shows user's id, and this is working, but then, by pressing the button, I want to send the user to a detail view controller.

you can have an idea of what I'm looking for here and here

tried to apply those solutions, but I think I'm missing something. This is another example of what I'm seeking

enter image description here

this is my class declaration:

import UIKit
import MapKit
import CoreLocation
import Parse

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UIActionSheetDelegate {

and this is the part of the code where I'd like to create annotations with buttons:

    // MARK: - Create Annotation

    func createAnnotations(point: PFGeoPoint, address: String)
    {
        println("*** this evaluates n.3 ***")
        var query = PFUser.query()


        query?.whereKey("location", nearGeoPoint: point, withinKilometers: withinKms)
        query?.orderByAscending("location")  //MARK:  Put list in order

        //MARK: Not include current user on the map
        var me = PFUser.currentUser()?.username
        query?.whereKey("username", notEqualTo: me!)

        query?.limit = self.kLimitNumberForQueryResults


        query?.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in

            if error == nil
            {
                for(var i = 0; i < objects!.count; i++) {

                    let user = objects![i] as! PFUser
                    var myHomePin = MKPointAnnotation()
                    let userPoint = user["location"] as! PFGeoPoint
                    myHomePin.coordinate = CLLocationCoordinate2DMake(userPoint.latitude, userPoint.longitude)
                    myHomePin.title = user.username

 //MARK: core of the problem                   
//                    let detailButton : UIButton = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as! UIButton
//                    myHomePin.rightCalloutAccessoryView = detailButton
//




//                    myHomePin.subtitle = address
                    self.mapView.addAnnotation(myHomePin)
                    //                    self.closeUsersArray.append(user.username!) //MARK: Test

                }






//                    println("this is the array of users * \(self.closeUsersArray) *") //MARK: Test
            }
            else
            {
                println("Error: " + error!.localizedDescription)
            }

        })

    }

thanks in advance!

Community
  • 1
  • 1
biggreentree
  • 1,633
  • 3
  • 20
  • 35

1 Answers1

2

Use the 'viewForAnnotation' map view delegate method to setup left and rightcalloutAccessories. and also UIButton.buttonWithType is replaced, this will work: Edit: all delegate methods you need but I didn't though your createAnnotation function because you said its working fine

class MapViewController: UIViewController, MKMapViewDelegate //
{
    @IBOutlet weak var mapView: MKMapView!{ //make sure this outlet is connected 
        didSet{
            mapView.delegate = self
        }
    }

    // MARK: - Map view delegate

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        var view = mapView.dequeueReusableAnnotationViewWithIdentifier("AnnotationView Id")
        if view == nil{
            view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "AnnotationView Id")
            view!.canShowCallout = true
        } else {
            view!.annotation = annotation
        }

        view?.leftCalloutAccessoryView = nil
        view?.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure)
        //swift 1.2
        //view?.rightCalloutAccessoryView = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as UIButton

        return view
    }

    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        //I don't know how to convert this if condition to swift 1.2 but you can remove it since you don't have any other button in the annotation view
        if (control as? UIButton)?.buttonType == UIButtonType.DetailDisclosure { 
                mapView.deselectAnnotation(view.annotation, animated: false)
                performSegueWithIdentifier("you're segue Id to detail vc", sender: view)
            }
        } 
    }

    //Your function to load the annotations in viewDidLoad

}
Lukas
  • 3,423
  • 2
  • 14
  • 26
  • I tried by putting you func above my "createAnnotations", bu got this: MapViewController.swift:192:51: Extra argument 'type' in call – biggreentree Oct 14 '15 at 11:44
  • Are you using Swift1.2? that code works fine on swift2.0 – Lukas Oct 14 '15 at 12:00
  • I recommend updating :) – Lukas Oct 14 '15 at 12:02
  • Ps, you're not supposed to put the function in your function. thats a delegate method – Lukas Oct 14 '15 at 12:02
  • yes I will, but for now I have to close it on 1.2 :( then I'll switch but putting this aside, I added your func just above my "createAnnotations" func, as a separate func, is that right? – biggreentree Oct 14 '15 at 12:06
  • so I updated my mapView outlet, then, right above createAnnotations func, I added the // MARK: - Map view delegate block (here I deleted the third "}" ) then added createAnnotations func . but I got this error "MapViewController.swift:217:51: Extra argument 'type' in call" – biggreentree Oct 14 '15 at 13:23
  • yeah, thats because this code is for swift 2.0. you can replace it with the swift 1.2 version or you can also update to swift 2.0 – Lukas Oct 14 '15 at 18:53
  • I'm about to switch, but I need to show the app before my switch will be completed, do you know the swift 1.2 version? – biggreentree Oct 15 '15 at 09:20
  • I just edited the answer, you can replace it with swift 1.2 version in comment and you can delete the if statement since that'll probably give the same error message – Lukas Oct 15 '15 at 09:48
  • I'll check your answer as accepted, your code is great! you saved my day and explained everything very well!! could I ask of your help in the future? (later I'll erase all this comments) your if statement is working well for now, and since I could need to add a second button, I'll keep it. – biggreentree Oct 15 '15 at 10:27
  • you're very welcome. and yeah, feel free to contact me. I'm also learning swift so I'd be happy to help – Lukas Oct 15 '15 at 10:37
  • didn't know how to contact you in different way :) (I will delete this comment) but after your solution, my mapView's `self.mapView.showsUserLocation = true` is not working anymore, any idea? thanks! – biggreentree Oct 25 '15 at 11:02
  • when do you want it to be visible? if you want that to happen when mapView outlet is set on startup, put that code in the didSet closure but that will be false when user scrolls to somewhere else and you can check if the user's location is visible with mapView.userLocationVisible property and if false set showsUserLocation true. You can see the to properties as a setter(showsUserLocation) and a getter(userLocationVisible) I hope I answered your question – Lukas Oct 25 '15 at 11:50
  • I tried adding `self.mapView.showsUserLocation = true` to the didSet of MapView, right below `mapView.delegate = self`. but i doesn't work – biggreentree Oct 25 '15 at 12:56
  • It's probably because you set the annotations to be visible in viewdidload or somewhere after the map view is set. Try this, var locstionBool = map view.userLocationVisible {didSet {if.!locationBool {mapView.showsUserLocation = true } } } – Lukas Oct 25 '15 at 13:31
  • I typed it on my phone so pardon the typos – Lukas Oct 25 '15 at 13:32
  • never mind typos, yes notation are handles by your two func and my third one, so where should I put `var locationBool = mapView.userLocationVisible {didSet {if.!locationBool {mapView.showsUserLocation = true } }` ?? maybe in mapView's didSet? – biggreentree Oct 25 '15 at 13:45
  • No, it should be on its own, not in any function or property – Lukas Oct 25 '15 at 15:06
  • hi @Lukas, could you help me here? http://stackoverflow.com/questions/33606788/swift-how-to-get-parses-many-users-name-and-photo – biggreentree Nov 09 '15 at 17:43
  • just did, didn't have time to explain but I hope the code is self explanatory – Lukas Nov 09 '15 at 19:42
  • you were fast, but problem isn't solved yet, I updated the code of that question – biggreentree Nov 11 '15 at 00:25