When are swift functions called in programs where no function call is visible?

238 views Asked by At

The example below is taken from Mapbox, and shows how to mark a location on a map with an annotation. I understand that viewDidLoad is called when the app starts and thats what runs everything inside the viewDidLoad function.

I don't understand how the last two functions in this program are called(which both seem to have the name mapView). I see no reference to them inside viewDidLoad

import Mapbox

class ViewController: UIViewController, MGLMapViewDelegate {
  override func viewDidLoad() {
    super.viewDidLoad()

    let mapView = MGLMapView(frame: view.bounds)
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Set the map’s center coordinate and zoom level.
    mapView.setCenter(CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407), zoomLevel: 12, animated: false)
    view.addSubview(mapView)

    // Set the delegate property of our map view to `self` after instantiating it.
    mapView.delegate = self

    // Declare the marker `hello` and set its coordinates, title, and subtitle.
    let hello = MGLPointAnnotation()
    hello.coordinate = CLLocationCoordinate2D(latitude: 40.7326808, longitude: -73.9843407)
    hello.title = "Hello world!"
    hello.subtitle = "Welcome to my marker"

    // Add marker `hello` to the map.
    mapView.addAnnotation(hello)
  }

  // Use the default marker. See also: our view annotation or custom marker examples.
  func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
    return nil
  }

  // Allow callout view to appear when an annotation is tapped.
  func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
    return true
  }
}
3

There are 3 answers

1
Robert Dresler On BEST ANSWER

These are delegate methods declared by protocol called MGLMapViewDelegate which is implemented to your class

class ViewController: UIViewController, MGLMapViewDelegate { ... }

By setting delegate of some object as your controller (= self) like you did with your MGLMapView in viewDidLoad

mapView.delegate = self

you're saying that when some method is called on mapView's delegate, method which you've implemented like mapView(_:viewFor:) -> MGLAnnotationView? will be called.


Anyway, your mapView should be instance variable, otherwise you lost reference for it

class ViewController: UIViewController, MGLMapViewDelegate {

    var mapView: MGLMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        mapView = MGLMapView(frame: view.bounds)
        ...
    }
}
3
Shehata Gamal On

This

mapView.delegate = self

with

class ViewController: UIViewController, MGLMapViewDelegate {

is responsible for calling them , inside the MapKit frameWork the class MKMapView has a delegate property when you set the right delegate interally this happens

delegate?.mapView(self,//)

also you shouldn't return nil here

func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
1
Mohmmad S On

They are delegate functions, not ordinary function that you call, more like functions that get called based on an action, and you did set the MapView.delegate to self so when the functions gets called in the MapView regarding the case that called them they will get back to the implemented side in your self in this case the UIViewController, i suggest reading more about delegates here, so shortcut answer, the functions are not called in the same class.