swift - 如何在 map 下方的固定大小组件中显示 MKPinAnnotationView 数据(例如标题、副标题)而不是图钉上方的弹出窗口?

标签 swift mkmapview mapkit mkannotation mkpinannotationview

我的 swift ios 应用程序中有一张 map ,上面全是标记。因此我决定使用从这里获取的标记聚类:https://github.com/ribl/FBAnnotationClusteringSwift

在我的应用程序中实现它后,我看到了图钉和簇,这很酷。

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

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)!)

最后,我将数据放在 map 上,同时检查每个图钉是簇还是普通图钉:

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。但我想达到不同的效果。

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

enter image description here

这是点击 map 上的任意点后立即发生的情况:

enter image description here

当然,一旦用户滚动 map ,这个组件就会消失。

这在 Swift 中可以实现吗?

最佳答案

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

在 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”。您可以从 MapViewDelegate 方法调用“tapShowView”方法。

    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
    }

}

然后为了防止在您触摸此委托(delegate)方法中的注释时显示任何标注..

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

添加:

 annotationView?.canShowCallout = true   

编辑 2: 如果您需要在用户滚动 map 等时切换 View 。您可以在区域中执行此操作并更改委托(delegate)方法。

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

我建议您好好看看 MKMapView 委托(delegate)函数。你可以用它们做很多很酷的事情。任何时候你添加像 UITableView/UICollectionView/MKMapView 等的东西...花几分钟滚动浏览委托(delegate)函数。某些委托(delegate)函数的强大程度真是令人惊叹。如果您需要其他任何东西,我今天剩下的时间都在。

关于swift - 如何在 map 下方的固定大小组件中显示 MKPinAnnotationView 数据(例如标题、副标题)而不是图钉上方的弹出窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35760205/

相关文章:

swift - 使用 FCM 的推送通知不适用于我的所有设备

swift - 带容器 View 的分段控件

ios - 在 IOS 8 中的 MKMapView 上添加按钮

ios - 如何像 Apple 的本地 map 应用程序那样进行本地搜索自动完成?

objective-c - iOS 和 Android 上两点之间的不同距离

swift - 如何在 Xcode 源代码编辑器扩展中获取当前工作区路径?

ios - Firebase - 跨多个位置的原子写入不起作用

swift - map View 上的倒圆圈叠加(MapKit、MKOverlay、Swift)

iphone - MKMapView使用名称在国家/地区上放置图钉

ios - 单击时 MapView 自定义图钉不显示详细信息