Дублирование MapKit, аннотаций и addSubview

#swift #xcode

#swift #xcode

Вопрос:

Я реализовал подпись под аннотациями с заголовком. Я сделал это с помощью addSubview и label. Я не понимаю, почему имена дублируются после следующего чтения точек. Сами точки загружаются корректно, проблема только с заголовком.

экран: [1]: https://i.stack.imgur.com/6phGQ.png

     func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard annotation is MKPointAnnotation else { return nil }
  
        let identifier = "Annotation"
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: nil, reuseIdentifier: identifier)
       
   
            annotationView!.isEnabled = true
            annotationView!.canShowCallout = true
            annotationView!.annotation = annotation
            annotationView!.displayPriority = .required

 
        } else {
           
            annotationView!.annotation = annotation
          
        }
        
        let detailAnnotation = annotation as! WaypointsAnnotation
 
        
          if (detailAnnotation.type == "Waypoint") {
   
              let imageview = UIImageView(frame: CGRect(x: -15, y: -15, width: 30, height: 30))
              let label = UILabel()
              label.frame = CGRect(x: 0, y: 1, width: 60, height: 30)
              label.textAlignment = .center
              label.font = UIFont.boldSystemFont(ofSize: 12)
           
              label.text = annotation.title as? String
              label.textColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
              imageview.addSubview(label)
            
         
              annotationView!.image = UIImage(named: "point8")
              annotationView!.addSubview(imageview)
             
   
          }
         
      
        let rightButton = UIButton(type: .detailDisclosure)
        
        rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
                   annotationView?.rightCalloutAccessoryView = rightButton
      
        return annotationView
    }


  

Ответ №1:

Ваш код вызывает dequeueReusableAnnotationView, чтобы попытаться повторно использовать ранее использованный MKAnnotationView . Затем, независимо от того, перерабатываете ли вы представление аннотации, вы добавляете ярлык и представление изображения.

Если вы повторно используете ранее использованное представление аннотаций, к нему уже будут прикреплены ярлык и изображение. Каждый раз, когда вы перерабатываете an MKAnnotationView , вы добавляете к нему дополнительный вид изображения и ярлык. Не делайте этого.

Вы должны поместить код, который добавляет вид метки и изображения внутри if annotationView == nil инструкции. Таким образом, вы добавите представление изображения и метку к представлению аннотаций только при первом его создании.

Вместо того, чтобы создавать общий MKAnnotationView и настраивать его, вы можете создать пользовательский подкласс MKAnnotationView , к которому уже прикреплены поля label и image view.

Комментарии:

1. Хорошо, я передал вид метки и изображения в оператор annotationView == nil, и он работает (не дублируется), но теперь при перезагрузке каждый вывод имеет другое название. При первой загрузке все в порядке.

2. Вам нужен способ получить доступ к существующей надписи и представлению изображения, чтобы изменить их при переработке. Вот почему я предложил создать пользовательский подкласс MKAnnotationView . У него будут выходы к добавленным вами пользовательским полям. Вы бы попытались получить переработанный. Если вы получите его, вы просто установите текст его метки и изображение изображения. Если нет, вы бы создали новый и сделали то же самое.