【问题标题】:Displaying annotations on MapView with selection of a collectionView cell通过选择 collectionView 单元格在 MapView 上显示注释
【发布时间】:2020-09-27 12:32:00
【问题描述】:

我有一个程序应该根据选择的 collectionView 单元格在地图上显示注释。但是目前,当尝试选择一个 collectionView 单元格时,地图上什么也没有出现。

这里是代码。

import UIKit
import MapKit

struct PlacesOnMap {
var name: String
var latitude: Double
var longitude: Double

init(name: String, latitude: Double, longitude: Double) {
self.name = name
self.latitude = latitude
self.longitude = longitude
}
}

class CollectionViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, MKMapViewDelegate {

@IBOutlet weak var mapView1: MKMapView!
var placesVal = [PlacesOnMap(name: "place 1", latitude: 12.9716, longitude: 77.5946),
                 PlacesOnMap(name: "place 2", latitude: 12.2958, longitude: 76.6394),
PlacesOnMap(name: "place 3", latitude: 11.4102, longitude: 76.6950)
]
var buildings = [PlacesOnMap(name: "buildings 1", latitude: 12.9716, longitude: 77.5946),
PlacesOnMap(name: "buildings 2",  latitude: 12.2958, longitude: 76.6394)
]
var recreation = [PlacesOnMap(name: "recreation 1", latitude: 28.54693, longitude: -81.393071),
PlacesOnMap(name: "recreation 2", latitude: 28.538523, longitude: -81.385399),
PlacesOnMap(name: "recreation 3", latitude: 28.542817, longitude: -81.378117),
PlacesOnMap(name: "recreation 4", latitude: 28.538985, longitude: -81.404694)
]

let reuseIdentifier = "cell" // also enter this string as the cell identifier in the storyboard
var items = ["Places", "Buildings", "Recreations"]
var displayCategoryText: String = ""


override func viewDidLoad() {
    super.viewDidLoad()

     mapView1?.delegate = self
}

// MARK: - UICollectionViewDataSource protocol
// tell the collection view how many cells to make
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.items.count
}

// make a cell for each cell index path
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // get a reference to our storyboard cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell

    // Use the outlet in our custom class to get a reference to the UILabel in the cell
    cell.myLabel.text = self.items[indexPath.item]
    cell.backgroundColor = UIColor.cyan // make cell more visible in our example project
    return cell
}

// MARK: - UICollectionViewDelegate protocol
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    // handle tap events
    displayCategoryText = String(indexPath.item)
    checkDisplayCategoryText()
}

func checkDisplayCategoryText() {
    if displayCategoryText == "0" {
        setPlacesAnnotations()
    }
    if displayCategoryText == "1" {
        setBuildingsAnnotations()
    }
    if displayCategoryText == "2" {
        setRecreationAnnotations()
    }
}

func setPlacesAnnotations() {
       let places = placesVal.map { placeOnMap -> MKPointAnnotation in
       let place = MKPointAnnotation()
       place.coordinate =  CLLocationCoordinate2D(latitude: placeOnMap.latitude, longitude: placeOnMap.longitude)
       place.title = placeOnMap.name
       return place
       }
       mapView1?.removeAnnotations(mapView1.annotations)
       mapView1?.addAnnotations(places)
   }

   func setBuildingsAnnotations() {
       let places = buildings.map { placeOnMap -> MKPointAnnotation in
       let place = MKPointAnnotation()
       place.coordinate =  CLLocationCoordinate2D(latitude: placeOnMap.latitude, longitude: placeOnMap.longitude)
       place.title = placeOnMap.name
       return place
       }
       mapView1?.removeAnnotations(mapView1.annotations)
       mapView1?.addAnnotations(places)
   }

   func setRecreationAnnotations() {
       let places = recreation.map { placeOnMap -> MKPointAnnotation in
       let place = MKPointAnnotation()
       place.coordinate =  CLLocationCoordinate2D(latitude: placeOnMap.latitude,  longitude: placeOnMap.longitude)
       place.title = placeOnMap.name
       return place
       }
       mapView1?.removeAnnotations(mapView1.annotations)
       mapView1?.addAnnotations(places)
   }


   func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        guard let annotationTitle = view.annotation?.title else
              {
                  print("Unable to retrieve details")
               return
              }
     print("User tapped on annotation with title: \(annotationTitle!)")
   }

}
extension CollectionViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let cellsAcross: CGFloat = 3
    var widthRemainingForCellContent = collectionView.bounds.width
    if let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout {
        let borderSize: CGFloat = flowLayout.sectionInset.left + flowLayout.sectionInset.right
        widthRemainingForCellContent -= borderSize + ((cellsAcross - 1) * flowLayout.minimumInteritemSpacing)
    }
    let cellWidth = widthRemainingForCellContent / cellsAcross
    return CGSize(width: cellWidth, height: cellWidth)
}

}

class MyCollectionViewCell: UICollectionViewCell {

@IBOutlet weak var myLabel: UILabel!

}

这是故事板的照片。

Picture of storyboard

我将如何解决这个问题,以便根据选择的集合视图单元格在 mapView 上显示正确的注释?

【问题讨论】:

    标签: ios swift mapkit mapkitannotation


    【解决方案1】:

    我假设您已在 Storyboard 中正确设置了 UICollectionView 委托和数据源。

    当您选择您设置的单元格时:

    displayCategoryText = String(indexPath.item)
    

    但是你不会对那个变量做任何事情。您需要调用一个方法,该方法可以使用该变量的值从数据模型中提取正确的信息,然后将注释添加到地图中。

    【讨论】:

    • 变量是否没有在 viewDidLoad 函数中通过行调用,'if displayCategoryText == "0" { setPlacesAnnotations() }'?
    • 在 ViewDidLoad 中检查变量的值并调用 setPlacesAnnotations 是否等于“0”,但随后应用程序流离开 ViewDidLoad 并且永远不会返回。您在didSelectItemAt 中所做的只是更改变量的值。这与 ViewDidLoad 中发生的检查无关,因为应用程序流不会从那里返回。这就是为什么您需要在更改后启动检查/方法。
    • 更改后如何启动检查/方法?
    • 您需要编写一个函数并在为 displayCatehoryText 设置新值后调用它。您需要了解此变量的所有可能值,并在您的函数中检查实际值并执行适当的操作。
    • 我已经更新了我的代码以包含一个检查 displayCategoryText 可能情况的函数,但在地图上仍然没有任何注释。
    【解决方案2】:

    我为此苦苦挣扎了整整 3 天,并阅读了几乎所有谷歌文章,直到找到有帮助的一篇。

    首先在 mapview(didSelect: ) 中获取注释索引

    让 index = (self.mapView.annotations as NSArray).index(of: anno) *Anno 是我的自定义注释视图的 view.annotation 常量

    然后,如果您希望 collectionview 通过点击注释滚动到正确的单元格,请将其添加到您的 didSelect 函数中:

    让 path = IndexPath(row: index, section: 0) self.collectionView.scrollToItem(at: path, at: .centeredHorizo​​ntally, animated: true)

    然后,在 collectionView cellForItemAt 中,我添加了以下内容:

    self.mapView.selectAnnotation(self.mapView.annotations[indexPath.row], animated: false)

    这将选择与您的 mapView 注释的 indexPath.row 对应的注释!

    希望有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多