Gold challenge:Dropping Pins

#1

My Code:

[code]
//When push the User location button
func showMyLoc(sender: UIButton) {
locMngr.desiredAccuracy = kCLLocationAccuracyBest
let authorizationStatus = CLLocationManager.authorizationStatus()

    if .NotDetermined == authorizationStatus {
        locMngr.requestWhenInUseAuthorization()
    }
    else if authorizationStatus == .AuthorizedAlways || authorizationStatus == .AuthorizedWhenInUse {
        locMngr.requestLocation()
        
        mymapView.showsUserLocation = true
        mymapView.showsScale = true
    }
}

//Delegate of show User’s location
func locationManager(manager: CLLocationManager, didUpdateLocations locations:[CLLocation] ) {
if let lastUserLocation = locations.last {
let zoomedInCurrentLocation = MKCoordinateRegionMakeWithDistance(lastUserLocation.coordinate, 500, 500)

        mymapView.setRegion(zoomedInCurrentLocation, animated: true)
    }
}

//When push the Drop pin button
func showMyPins(pinsBtn: UIButton) {
if true == mymapView.showsUserLocation {
mymapView.showsUserLocation = false
mymapView.showsScale = false
}

    let myAnnotation = MKPointAnnotation()
    myAnnotation.title = "PinsTitle"
    myAnnotation.subtitle = "Is Here"
    myAnnotation.coordinate = xxxxxxxxx
    mymapView.addAnnotation(myAnnotation)
   let zoomedInCurrentLocation = MKCoordinateRegionMakeWithDistance(myAnnotation.coordinate, 500, 500)
    mymapView.setRegion(zoomedInCurrentLocation, animated: true)
}

//Delegate of Drop pin
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKindOfClass(MKUserLocation) {
return nil
}

    var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("Test") as? MKPinAnnotationView
    
    if pinView == nil {
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "Test")
        pinView!.canShowCallout = true
        pinView!.animatesDrop = true
        pinView!.pinTintColor = UIColor.purpleColor()
        let myAnnotation = MKPointAnnotation()
        myAnnotation.title = PinsTitle[PinsTitleIdx]
        myAnnotation.subtitle = "Test Pin"
        myAnnotation.coordinate = Postion[PinsTitleIdx]
        pinView!.annotation = myAnnotation
    }
    else {
        pinView!.annotation = annotation
    }
    
    return pinView
}[/code]

Problem:
When the application is launched, and push show user location button [color=#FF0000]FIRST[/color], and then push drop pin button,
case 1.If the code below in “showMyPin” is not exist:

let zoomedInCurrentLocation = MKCoordinateRegionMakeWithDistance(myAnnotation.coordinate, 500, 500) mymapView.setRegion(zoomedInCurrentLocation, animated: true)
in this case, the delegate:

is not called, there is no pin on map

case 2.If red code is exist:
in this case, the delegate:

is called, pin is dropped on map.

When the application is launched, and push drop pin button [color=#FF0000]FIRST[/color],
in this case, even if the red code is not exist, the delegate:

is still called too, pin is dropped on map.

Dose the setRegion function influence the delegate call?
Why the diffrent sequence of push button result in delegate be called or not be called?

#2

That is not the proper way to post code on a computer programming forum. You MUST use code tags–no exceptions–so that the indenting is preserved.

#3

I have edited my topic.
Now is it OK?

#4

It’s better! But all code should be in code tags (see below). Red highlighting is not necessary.

According to your description, the problem that you are having is caused by clicking on this button or that button. Why is it that you think that executing the following code:

let myAnnotation = MKPointAnnotation() myAnnotation.title = "PinsTitle" myAnnotation.subtitle = "Is Here" myAnnotation.coordinate = xxxxxxxxx mymapView.addAnnotation(myAnnotation)

should depend on the user clicking a button?

#5

It’s better! But all code should be in code tags (see below). Red highlighting is not necessary.

According to your description, the problem that you are having is caused by clicking on this button or that button. Why is it that you think that executing the following code:

let myAnnotation = MKPointAnnotation() myAnnotation.title = "PinsTitle" myAnnotation.subtitle = "Is Here" myAnnotation.coordinate = xxxxxxxxx mymapView.addAnnotation(myAnnotation)

should depend on the user clicking a button?[/quote]

If user don’t click the button, the mymapView.addAnnotation(myAnnotation) will not be called, so the delegate:

will not be called. Is it right? :open_mouth:

#6

[quote]If user don’t click the button, the

will not be called,[/quote]

Does all the code in your app have to go inside an @IBAction function connected to a button in order to execute?

My tests show that calling mapView.addAnnotation(:slight_smile: is necessary before calling setRegion(:animated:).

#7

Here is how I implemented the challenge:

struct Locations {
    var name: String
    var lat: Double
    var long: Double
    
    init(name: String, lat: Double, long: Double) {
        self.name = name
        self.lat = lat
        self.long = long
    }
}

override func loadView() {
    super.loadView()

    ...

    //create array of location objects:
    var locations = [Locations]()
    locations.append(Locations(name: "New York City", lat: 40.730872, long: -74.003066))
    locations.append(Locations(name: "London", lat: 51.5074, long: 0.1278))
    locations.append(Locations(name: "Tokyo", lat: 35.6895, long: 139.6917))

    //drop location pins onto map:
    for location in locations {
        let dropPin = MKPointAnnotation()
        dropPin.coordinate = CLLocationCoordinate2DMake(location.lat, location.long)
        dropPin.title = location.name
        mapView.addAnnotation(dropPin)
    }

    //create button to toggle pins:
    let pinButton = UIButton(type: .system)
    pinButton.setTitle("Pins", for: .normal)
    pinButton.backgroundColor = UIColor.white.withAlphaComponent(0.5)
    pinButton.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
    pinButton.translatesAutoresizingMaskIntoConstraints = false
    pinButton.addTarget(self, action: #selector(selectPin(_:)), for: .touchUpInside)
    view.addSubview(pinButton)
    pinButton.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor, constant: -8).isActive = true
    pinButton.leftAnchor.constraint(equalTo: margins.leftAnchor).isActive = true

}

//keeps track of current pin index:
var selectedAnnotationIndex: Int = -1

//function call when button is pressed:
func selectPin(_ button: UIButton) {
    
    //data checks:
    if !(mapView.annotations.count > 0) {
        return
    }
    
    //go to next annotation or back to start if last one:
    selectedAnnotationIndex += 1
    if selectedAnnotationIndex >= mapView.annotations.count {
        selectedAnnotationIndex = 0
    }
    
    //select pin and animate map:
    let annotation = mapView.annotations[selectedAnnotationIndex]
    let zoomedInCurrentLocation = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 5000, 5000)
    mapView.setRegion(zoomedInCurrentLocation, animated: true)
}