Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么时候在Swift中调用mapView:viewForAnnotation?_Swift_Mapkit_Mapkitannotation - Fatal编程技术网

什么时候在Swift中调用mapView:viewForAnnotation?

什么时候在Swift中调用mapView:viewForAnnotation?,swift,mapkit,mapkitannotation,Swift,Mapkit,Mapkitannotation,根据每次调用addAnnotation方法时,都会调用mapView:viewForAnnotation 但是,以下代码只调用了一次mapView:viewForAnnotation。我有几个注释,但“视图调用”只打印了一次。我想这和线有关吧 import UIKit import MapKit import CoreLocation class ViewController: UIViewController, UITextFieldDelegate, MKMapViewDelegate,

根据每次调用
addAnnotation
方法时,都会调用
mapView:viewForAnnotation

但是,以下代码只调用了一次
mapView:viewForAnnotation
。我有几个注释,但“视图调用”只打印了一次。我想这和线有关吧

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
    }
简而言之,当注释位于地图视图的可见部分内时,将调用
mapView(uuxAE:viewFor:)
。即,要么(a)注释已添加到地图视图中,并且随着
区域的变化而下降,要么(b)
区域的变化导致以前不可见的注释现在消失。不用说,只有在设置映射视图的委托(以编程方式或在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(uu:viewFor:)
。因此,如果只调用了一次,可能需要确认
注释是
MKUserLocation
还是您添加的注释之一。

另外,请确保将mapview的委托属性设置为self

mapview.delegate = self

您也可以通过使用连接检查器(Interface Builder)将mapview的代理出口连接到ViewController来实现这一点。

我不确定if(placenum==places.count)
模式的意图,但它对我来说似乎是不必要和多余的。你怎样才能到达循环的终点,而这两个循环又是不相等的呢?而且,如果出于某种原因,其中一个注释没有被添加,为什么您不想显示已经添加的注释呢?@Rob I对代码进行了过度简化。现在,相关部分被添加回来。如果“坐标”落在当前地图视图区域中,则为placenum++。因此,我认为您只需要
If(placenum>0)
,不是吗?但是,如果只添加可见矩形内的注释,则根本不需要
showAnnotations
,对吗?
showAnnotations
的目的是更改地图视图以适应添加的注释,但如果它们都可见,则无需更改,对吗?@Rob
placenum
的目的是查看是否所有位置都在可见矩形中。如果是这样,我将使用showAnnotations来放大(放大)到最合适的视图,并显示它们。如果没有,我将只在visible rect中显示这些内容,这在当前代码中不起作用。我必须点击地图来触发添加注释。我计划通过在visible rect中创建另一个注释列表来修复它,并在列表中使用
showAnnotations
。另一方面,你的答案观察1似乎指向了另一种方式……首先,一定要将所有这些地图内容移到主线程,一些奇怪的行为可能会消失。第二,我只是提出了“何时缩放”的逻辑问题,因为这在我看来是倒退的,但听起来这是一个有意识的决定,所以在这方面你想做什么就做什么。祝你好运大约2,当应用程序启动时,除了用户的当前位置外,没有其他注释。因此,我使用
didUpdateUserLocation
设置默认区域。一旦用户发出请求并从internet获取位置列表,该区域将相应地更新为
showAnnotations
,如果使用“userTrackingMode”,是否仍可以在mapview中设置区域的增量/大小?因为您在地图重新居中后立即停止位置服务,这不太可能是问题的根源,所以我删除了我答案中的这一部分。我只是担心你可能更改了位置,使注释不再可见的风险…@ChrisSchlitt我们来这里是为了拯救对方:)