如何在地图下方的固定大小的组件中显示MKPinAnnotationView数据(例如标题,副标题)而不是针脚上方的弹出窗口?

时间:2016-03-02 23:20:40

标签: swift mkmapview mapkit mkannotation mkpinannotationview

我的swift ios应用程序中有一张地图,里面装满了标记。因此,我决定使用从此处获取的标记聚类:https://github.com/ribl/FBAnnotationClusteringSwift

在我的应用程序中实现它后,我看到了针脚和群集,所以很酷。

我就是这样做的 - 首先我调用我的webservice并获取每个引脚的所有数据并将其放入数组中:

func fetchRequests(radius: Double, lat: Double, lon: Double, completionHandler: (() -> Void)?){
    Alamofire.request(.GET, "http://mywebservice.com/fetchdata", parameters: ["param": "1"])
        .responseJSON { response in
            switch response.result {
            case .Success:

                self.array.removeAll()
                if let jsonData = response.result.value as? [[String: AnyObject]] {
                    for requestJSON in jsonData {
                        if let request = SingleRequest.fromJSON(JSON(requestJSON)){

                            let pinOne = FBAnnotation()
                            pinOne.coordinate = CLLocationCoordinate2D(latitude: request.latitude, longitude: request.longitude)
                            pinOne.title = request.title
                            pinOne.subtitle = request.discipline
                            self.array.append(pinOne)
                        }
                    }
                }
                self.clusteringManager.setAnnotations(self.array)
                completionHandler!()

                case .Failure(let error):
                print("SWITCH ERROR")
                print(error)
            }

    }
}

然后我实际上是从上面调用函数并执行:

let annotationArray = self?.clusteringManager.clusteredAnnotationsWithinMapRect(self!.mapView.visibleMapRect, withZoomScale:scale)
self?.clusteringManager.displayAnnotations(annotationArray!, onMapView:(self?.mapView)!)

最后我将数据放在地图上,同时检查每个引脚是簇还是正常引脚:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    var reuseId = ""
    if annotation.isKindOfClass(FBAnnotationCluster) {
        reuseId = "Cluster"
        var clusterView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
        clusterView = FBAnnotationClusterView(annotation: annotation, reuseIdentifier: reuseId, options: nil)

        return clusterView
    } else {
        reuseId = "Pin"
        var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
        pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        pinView!.calloutOffset = CGPoint(x: -5, y: 5)
        pinView!.canShowCallout = true
        pinView!.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure) as UIView

        return pinView   
    } 
}

到目前为止一切顺利。按预期工作,点击每个图钉后,我会看到titlesubtitle上面的弹出窗口。但我想达到不同的效果。

当用户点击一个引脚 - 而不是它上方的弹出窗口时 - 地图下方会出现一些方形组件。我正在寻找一些类似的解决方案作为示例,我在名为Periscope的应用程序中找到它 - 这是他们的地图在用户点击任何事件之前的样子:

enter image description here

这就是点击地图上的任何一点后发生的事情:

enter image description here

当用户滚动地图时,该组件当然会消失。

这可以在Swift中实现吗?

1 个答案:

答案 0 :(得分:2)

您可以尝试将UITapGestureRecognizer添加到MKMapView。然后,对于该操作,创建一个将在底部显示视图的函数。

在viewDidLoad()中添加了GestureRecognizer:

let showTap : UIGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapShowView:")
    myMapView.addGestureRecognizer(showTap)

然后你的功能可能是这样的。

 func tapShowView(sender:UIGestureRecognizer) {

   //Animate UIView in......

   //Or just add your UIView.
    let viewHeight = CGFloat(80)
    let bottomView = UIView(frame: CGRect(x: 0, y: self.view.frame.height - viewHeight, width: self.view.frame.width, height: viewHeight))
        bottomView.backgroundColor = .whiteColor()

   //add buttons, navbar etc....

    self.myMapView.addSubview(bottomView)
    //OR if you add it in viewDidload and set to bottomView.hidden = true
    bottomView.hidden = false

}

请忽略任何语法错误,我没有坐在它上面的Xcode上。但这应该会给你一个推动力。如果你有任何疑问,我会在几个小时内醒来(凌晨1点31分在这里)...快乐的编码。

编辑:

我想我想念你的问题.....如果你想要显示" BottomView"当用户触摸注释时。你可以拨打" tapShowView" MapViewDelegate方法的方法。

    func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {

    if view.annotation!.isKindOfClass(FBAnnotationCluster) {

        print("cluster selected")

    } else {

        print("single pin selected")
        //Call method here to display BottomView.
        self.tapShowView() //Edit tapShowView to remove sender
    }

}

然后防止在此委托方法中触摸注释时显示任何标注..

   func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

ADD:

 annotationView?.canShowCallout = true   

编辑2: 如果您需要在用户滚动地图等时切换视图。您可以在区域中执行更改委托方法。

 func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool){
  //Just toggle the hidden property of the view.
  BottomView.hidden = true
 }

我建议你仔细看看MKMapView委托函数。你可以用它们做很多很酷的事情。任何时候你添加像UITableView / UICollectionView / MKMapView等东西...花几分钟滚动代理功能。令人惊讶的是,一些委托功能的强大程度。如果你还需要其他任何东西,我可以在一天的剩余时间里休息。