我的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
}
}
到目前为止一切顺利。按预期工作,点击每个图钉后,我会看到title
和subtitle
上面的弹出窗口。但我想达到不同的效果。
当用户点击一个引脚 - 而不是它上方的弹出窗口时 - 地图下方会出现一些方形组件。我正在寻找一些类似的解决方案作为示例,我在名为Periscope
的应用程序中找到它 - 这是他们的地图在用户点击任何事件之前的样子:
这就是点击地图上的任何一点后发生的事情:
当用户滚动地图时,该组件当然会消失。
这可以在Swift
中实现吗?
答案 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等东西...花几分钟滚动代理功能。令人惊讶的是,一些委托功能的强大程度。如果你还需要其他任何东西,我可以在一天的剩余时间里休息。