4

この投稿によるとaddAnnotation、メソッド を呼び出すたびに、mapView:viewForAnnotation呼び出されます

ただし、次のコードはmapView:viewForAnnotation1 回だけ呼び出されます。いくつかの注釈がありますが、「呼び出されたビュー」は一度だけ印刷されました。ひょっとして、スレと関係あるのかな?

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, UITextFieldDelegate, MKMapViewDelegate, CLLocationManagerDelegate {

    @IBOutlet var searchtext: UITextField!
    @IBOutlet var map: MKMapView!

    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.searchtext.delegate = self

        locationManager.delegate = self
        self.map.delegate = self

        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }

    func textFieldDidBeginEditing(textField: UITextField!) {    //delegate method
        var allAnnotations = self.map.annotations
        self.map.removeAnnotations(allAnnotations)
    }

    func textFieldShouldReturn(textField: UITextField!) ->Bool {
        textField.resignFirstResponder()

        //...

        let session = NSURLSession.sharedSession()

        var task = session.dataTaskWithURL(url!, completionHandler: { (date, response, error) -> Void in
            if (error != nil) {
                println(error)
            }else {
                var placenum = 0
                //placenum is to see if all the places are in the visible rect. If so I will use showAnnotations to zoom (in) to the best-fitted view show them. If not, I will only show these in the visible rect
                for place in places {
                    //...
                    if (regionContains(self.map.region, coordinate)) {
                        placenum = placenum+1
                    }
                    self.map.addAnnotation(annotation)
                }

                if (placenum==places.count) {
                    self.map.showAnnotations(self.map.annotations, animated: true)
                }
            }

        })

        task.resume()

        return true
    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

        //...
        self.map.setRegion(region, animated: false)

        locationManager.stopUpdatingLocation()
    }

    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
        println("view called")

        return nil
    }
4

2 に答える 2

3

また、mapview のデリゲート プロパティを必ず self に設定してください。

mapview.delegate = self

これは、Connection Inspector (Interface Builder) を使用して、mapview のデリゲート アウトレットを ViewController に接続することでも実行できます。

于 2015-07-24T06:18:25.143 に答える
3

つまり、mapView(_:viewFor:)注釈がマップ ビューの表示部分に収まったときに呼び出されます。つまり、(a) 注釈がマップ ビューに追加され、それが に含まれるregionか、(b)region以前は表示されなかった注釈が現在表示されるように変更されているかのいずれかです。言うまでもなく、このメソッドは、(プログラムまたは Interface Builder で) マップ ビューのデリゲートを設定した場合にのみ呼び出されます。

ちなみに、の完了ハンドラはdataTask(with:completionHandler:)メインスレッドでは呼び出されません。したがって、UI の更新は明示的にメイン スレッドにディスパッチする必要があります。

DispatchQueue.main.async {
    for place in places {
        //...
        placenum = placenum + 1
        self.map.addAnnotation(annotation)
    }

    self.map.showAnnotations(self.map.annotations, animated: true)
}

上記のように、マップ ビューとのやり取りがメイン スレッドで行われるようにすることをお勧めします。

ところで、地図上にユーザーの位置を表示している場合、それ自体mapView(_:viewFor:)が呼び出されることに注意してください。そのため、一度しか呼び出されていない場合は、が であるか、追加したアノテーションの 1 つでannotationあるかを確認する必要があります。MKUserLocation

于 2015-04-13T16:56:03.210 に答える