#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