自定义 MKMarkerAnnotationView 第一次在 UITableViewCell 中显示不正确

Custom MKMarkerAnnotationView not displayed correctly in UITableViewCell the first time

我有一个 table 视图,我想在 UITableViewCell 中显示自定义 MKMarkerAnnotationView。此 table 视图显示在专用的 ViewController 中,而 ViewController 显示在 TabBarController 中。第二个Tab显示一个地图(不过这里不重要)

我创建了一个继承自 MKMarkerAnnotationView 的 class "EdgePinViewAnnotation" 在我的情节提要中,在 TableView 中我添加了一个 UITableViewCell,其中包含一些标签和一个带有 class "EdgePinViewAnnotation"

的视图

在 UITableViewCell 的实现中,我正在初始化我的自定义 "EdgePinViewAnnotation"。 不幸的是,当 Cell 显示在 table 中时,显示的是默认的 MKMarkerAnnotationView 而不是我自定义的 "EdgePinViewAnnotation".

当我滚动我的 TableView 时单元格离开屏幕然后刷新它正确显示我的 "EdgePinViewAnnotation"。

为什么第一次显示不正确?

这里是我为自定义 MKMarkerAnnotationView 实现的代码

class EdgePinViewAnnotation: MKMarkerAnnotationView {

    override var annotation: MKAnnotation? {
        willSet {
            if let edgeAnnotation = newValue as? EdgePin {
                animatesWhenAdded = true
                isDraggable = true
                canShowCallout = true
                initRenderingProperties(pin: edgeAnnotation)
            }
        }
    }


    func initWith(edgePin:EdgePin) {
        animatesWhenAdded = false
        isDraggable = false
        canShowCallout = false
        initRenderingProperties(pin: edgePin)
    }

    func initRenderingProperties(pin edgePin:EdgePin) {
        glyphTintColor = UIColor.white
        glyphText = "\(edgePin.index)"
        markerTintColor = edgePin.renderingColor
    }

}

这是我的 UITableView 中的代码

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0 {
            if let cell = tableView.dequeueReusableCell(withIdentifier: CellId.DistanceConfigurationCellId, for: indexPath) as? DistanceConfigurationTableViewCell {
                cell.theLabel.text = findMe.edgePoints[indexPath.row].address
                let coord = findMe.edgePoints[indexPath.row].coordinate
                cell.coordinates.text = "Lat:\(coord.latitude) / Long:\(coord.longitude)"
                cell.theTextField.text = "\(findMe.edgePoints[indexPath.row].distance)"
                cell.theTextField.delegate = self
                cell.theTextField.tag = indexPath.row
                cell.theMarker.initWith(edgePin:findMe.edgePoints[indexPath.row])
                return cell
            }
        } else {
     return UITableViewCell()
    }
}



class DistanceConfigurationTableViewCell: UITableViewCell {

    @IBOutlet weak var theLabel: UILabel!
    @IBOutlet weak var coordinates: UILabel!
    @IBOutlet weak var theTextField: UITextField!

    @IBOutlet weak var theMarker: EdgePinViewAnnotation!

}

我找到了解决方案,即使我不是很理解它。

必须在

中配置 MKMarkerAnnotationView
tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 

而不是

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

然后下面的代码开始工作,MKMarkerAnnotationView 在每个 UITableViewCell 中正确显示

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0 {
            if let cell = tableView.dequeueReusableCell(withIdentifier: CellId.DistanceConfigurationCellId, for: indexPath) as? DistanceConfigurationTableViewCell {
                cell.theLabel.text = findMe.edgePoints[indexPath.row].address
                let coord = findMe.edgePoints[indexPath.row].coordinate
                cell.coordinates.text = "Lat:\(coord.latitude) / Long:\(coord.longitude)"
                cell.theTextField.text = "\(findMe.edgePoints[indexPath.row].distance)"
                cell.theTextField.delegate = self
                cell.theTextField.tag = indexPath.row

                return cell
            }
        } else {
     return UITableViewCell()
    }
}

  func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let theCell = cell as? DistanceConfigurationTableViewCell {

            theCell.theMarker.initWith(edgePin:findMe.edgePoints[indexPath.row])
        }
    }