Когда функции swift вызываются в программах, где не отображается вызов функции?

#ios #swift #mapbox #mglmapview

#iOS #swift #mapbox #mglmapview

Вопрос:

Приведенный ниже пример взят из Mapbox и показывает, как отметить местоположение на карте с помощью примечания. Я понимаю, что viewDidLoad вызывается при запуске приложения, и это то, что запускает все внутри функции viewDidLoad.

Я не понимаю, как вызываются последние две функции в этой программе (которые, похоже, имеют имя MapView). Я не вижу ссылок на них внутри 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
  }
}
  

Комментарии:

1. Это функции делегирования, читайте о делегатах здесь medium.com/@jamesrochabrun /…

2. @MohmmadS Я думал, что это могло быть так, но все, что я просматриваю, имеет другой синтаксис для делегатов, так что это своего рода сокращение?

3. прочитайте мой объясненный ответ @jacob

Ответ №1:

Это методы делегирования, объявленные протоколом, вызываемым MGLMapViewDelegate , который реализован в вашем классе

 class ViewController: UIViewController, MGLMapViewDelegate { ... }
  

Установив delegate какой-либо объект в качестве вашего контроллера ( = self ), как вы сделали со своим MGLMapView в viewDidLoad

 mapView.delegate = self
  

вы говорите, что когда какой-либо метод вызывается с помощью mapView делегата, будет вызван метод, который вы реализовали как mapView(_:viewFor:) -> MGLAnnotationView? .


В любом случае, вашей mapView должна быть переменная экземпляра, иначе вы потеряли ссылку на нее

 class ViewController: UIViewController, MGLMapViewDelegate {

    var mapView: MGLMapView!

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

Комментарии:

1. Однако, когда метод вызывается для делегата? Я просмотрел множество руководств, и мне не удалось выяснить, как я нахожу место, где в некоторых разделах кода написано «выполнить функцию MapView (_ MapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {» все, что я нахожу, показывает мне, как создать делегат и как создать протокол, но поскольку весь код локальный, очевидно, где он выполняется. И я не писал код сам, это из того примера, на который я ссылался. Меня не волнует, что в нем нужно изменить.

Ответ №2:

Это функции делегирования, а не обычная функция, которую вы вызываете, больше похожие на функции, которые вызываются на основе действия, и вы установили MapView.delegate значение self , поэтому, когда функции вызываются в MapView в отношении случая, который их вызвал, они вернутся к реализованной стороне в вашем self в данном случае UIViewController , я предлагаю прочитать больше о делегатах здесь, поэтому краткий ответ: функции вызываются не в том же классе.

Комментарии:

1. Как мне узнать, когда функция вызывается в mapview, и если они не вызываются в этом классе, как мне найти класс, в котором они вызываются? Все уроки или туториалы, которые я просматриваю, создают код с нуля, поэтому в уроке это очевидно.

Ответ №3:

Это

 mapView.delegate = self
  

с

 class ViewController: UIViewController, MGLMapViewDelegate {
  

отвечает за их вызов, внутри фреймворка MapKit класс MKMapView имеет свойство делегата, когда вы устанавливаете правильный делегат, это происходит внутри

 delegate?.mapView(self,//)
  

также вы не должны возвращать nil здесь

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

Комментарии:

1. это необязательное, MGLAnnotationView? которое он технически может вернуть nil , но не могли бы вы объяснить мне, почему он не должен, я хотел бы знать лучше

2. необязательность означает, что вы можете вернуть nil , но это скроет аннотацию, поскольку этот метод вызывается для каждой добавленной аннотации

3. о, спасибо, поэтому всякий раз, когда я хочу скрыть аннотацию, я бы просто возвращал nil