首页 > 解决方案 > 将 MapKit 注释连接到表格视图

问题描述

我有视图控制器,其中下半部分是表格视图,上半部分是地图。当它加载时,我调用一个 API 来获取附近的地方并将这些地方加载到一个数组中。加载数组后,我循环遍历数组以为每个位置的纬度、经度和名称设置注释,并且相同的数组是表格视图的数据。我想要做的是连接表格单元格和注释。

当有人点击表格视图时,我希望选择关联的注释并调用它来选择它。当有人点击注释时,我希望表格视图在表格视图中显示关联的单元格并突出显示它。我研究并发现 mapView 函数 didSelect 用于处理选定的注释,但我不知道如何(或者如果你可以)连接 2。现在我通过将数组位置放入注释的副标题来伪造它,这允许我从那个位置阅读所有细节,但这似乎是错误的做法。

...// load places into an array
            curBlipPlace.name = yelp.name
            curBlipPlace.distance = yelp.distance
            curBlipPlace.address1 = yelp.address1
            curBlipPlace.lat = yelp.lat
            curBlipPlace.lon = yelp.lon
            curBlipPlace.yelpId = yelp.yelpId
            curBlipPlace.yelp = yelp
            curBlipPlace.yelpArrayPosition = yelp.arrayPosition
            self.blipPlaces.append(curBlipPlace)

..// After filling array, sort it, loop to load annotations, and load to table
            self.blipPlaces.sort { $0.distance ?? 9999 < $1.distance ?? 9999 }
            for i in 0..<self.blipPlaces.count {
                if let lat = self.blipPlaces[i].lat, let lon = self.blipPlaces[i].lon {
                    let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
                    let annotation = MKPointAnnotation()
                    annotation.coordinate = coordinate
                    annotation.title = self.blipPlaces[i].name
                    annotation.subtitle = String(i)

                    self.map.addAnnotation(annotation)
                }
            }

            self.PlaceTableView.reloadData()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = PlaceTableView.dequeueReusableCell(withIdentifier: "fileCell", for: indexPath) as! BlipFileTVCell
    cell.placeLabel.text = "\(indexPath.row): \(blipPlaces[indexPath.row].name) - \(blipPlaces[indexPath.row].distance ?? 999)"
    return cell
}

..// Rube Goldberg way of connecting table cell and annotation by forcing array position into subTitle
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    print("CLICKED: \(String(describing: view.annotation?.title))")
    if let tempString = (view.annotation?.subtitle) as? String {
        print("ok... \(tempString)")
        if let tempInt = Int(tempString) {
            print(self.blipPlaces[tempInt].name)
        }
    }
}

有没有更好的方法来连接注释和表格单元格?有没有办法让单元格点击激活注释?

此外,由于点击的注释可能是表格中的最后一个单元格,如果表格单元格不在屏幕上,有没有办法向上“移动”表格单元格?如果有人为列表中的最后一项选择注释,有没有办法让表格单元格“向上滚动”,以便可以查看而不是在屏幕外?

-担

标签: iosswiftannotationstableviewmapkit

解决方案


实现自定义注释。

class CustomAnnotation: MKPointAnnotation {
    var index: Int!
}

将自定义注释添加到 mapView。

let annotation = CustomAnnotation()
annotation.coordinate = coordinate
annotation.title = "title"
annotation.subtitle = "subtitle"
annotation.index = 0 // 0...n
self.mapView.addAnnotation(annotation)

你可以index进去mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)

func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    if let annotation = view.annotation as? CustomAnnotation {
        print(annotation.index)
        // Get the cell by index
        // You can use `cellForRowAtIndexPath:`
        // Then select the cell
    }
}

编辑:

// when the table view is clicked 
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    for annotation in mapView.annotations {
        if let annotation = annotation as? CustomAnnotation, annotation.index == indexPath.row {
            // select annotation and show callout
            mapView.selectAnnotation(annotation, animated: true)
        }
    }
}

推荐阅读