Пользовательский вид выноски с xib

#ios #mapkit #mapkitannotation

#iOS #mapkit #обозначение mapkitannotation #mapkitannotation

Вопрос:

Я пытаюсь установить пользовательский вид выноски с помощью созданного мной xib, однако он не отображается.

Мой xib LocationInfo выглядит так введите описание изображения здесь

Я создал пользовательский класс uiview для представления в моем xib, чтобы установить фоновое изображение (не уверен, работает ли это, поскольку я не смог показать xib)

 import Foundation
import UIKit
import MapKit

class AddressView: MKPinAnnotationView{
    override func draw(_ rect: CGRect) {
        super.draw(rect);

        UIGraphicsBeginImageContext(self.frame.size)
        UIImage(named: "Location.Info-background")?.draw(in: self.bounds)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.backgroundColor = UIColor(patternImage: image!)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        //todo
    }

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        //todo
        return nil
    }
}
  

Мой пользовательский класс аннотации выглядит следующим образом

 import Foundation
import MapKit
import UIKit

class MapPin: MKPointAnnotation{
    var name: String
    var street: String
    var type: String
    var postCode: String

    init(name: String, street: String, type: String, postCode: String){
        self.name = name
        self.street = street
        self.type = type
        self.postCode = postCode
    }
}
  

и я пытаюсь использовать все это следующим образом в моем классе контроллера представления

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        CLGeocoder().reverseGeocodeLocation(manager.location!) { (placemarks, error) in
            if (error != nil){
                return
            }
            if placemarks?.count != nil{
                let pm = (placemarks?[0])! as CLPlacemark
                self.displayLocationInfo(placemark: pm)
            }
        }

        let spanX = 0.00725
        let spanY = 0.00725
        locationManager.stopUpdatingLocation()
        let location = locations.last! as CLLocation
        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: spanX, longitudeDelta: spanY))
        self.MapRSR.setRegion(region, animated: true)
        self.MapRSR.delegate = self

        let mapPin = MapPin(name: "", street: "", type: "", postCode: "")
        mapPin.coordinate = center
        mapPin.title = "test"

        self.MapRSR.addAnnotation(mapPin)
    }


    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let pin = mapView.dequeueReusableAnnotationView(withIdentifier: "LocationInfo") ?? AddressView(annotation: annotation, reuseIdentifier: "LocationInfo")
        pin.canShowCallout = true
        return pin
    }
  

Он просто не покажет мой xib-вид. Кто-нибудь знает, что я делаю не так или как я могу добиться желаемого эффекта, который выглядит примерно так.
введите описание изображения здесь

Ответ №1:

didSelectAnnotationView Загрузите xib из пакета и добавьте вложенный просмотр в представление аннотаций. здесь CustomXibCallout — это файл xib, а CustomCalloutView — MKAnnotationView .

 func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    if view.annotation!.isKindOfClass(MKUserLocation){
        return
    }

    //Custom xib
    let customView = (NSBundle.mainBundle().loadNibNamed("CustomXibCallout", owner: self, options: nil))[0] as! CustomCalloutView;

    let calloutViewFrame = customView.frame;

    customView.frame = CGRect(x: -calloutViewFrame.size.width/2.23, y: -calloutViewFrame.size.height-7, width: 315, height: 200)

    view.addSubview(customView)
}
  

в didDeselectAnnotationView удалить добавленный вид

 func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView)
{
    for childView:AnyObject in view.subviews{
        childView.removeFromSuperview();
    }
}
  

Пример для CustomCallout

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

1. эта часть let calloutViewFrame = customView.frame; customView.frame = CGRect(x: -calloutViewFrame.size.width/2.23, y: -calloutViewFrame.size.height-7, width: 315, height: 200) гарантирует, что представление не отображается. Когда я выну это, оно будет отображаться, но не так, как это должно быть очевидно

2. @NoSixties это просто для настройки нашего пользовательского размера представления аннотаций, в моем случае я использовал эти размеры фреймов для своих требований. в вашем случае задайте свой размер, какой хотите.

3. Я знаю, что пытался установить его, но, похоже, у меня это не работает.

4. откуда взялся «тестовый» идентификатор повторного использования в вашем примере приложения? потому что, когда я пытаюсь его реализовать, мой PIN-код исчезает, лол

5. «reuseId» для повторного использования представления аннотаций, такого как повторное использование строк tableview, можно использовать любой статический идентификатор. Этот идентификатор не имеет ничего общего с pin-кодом. я не знаю, как вы реализовали. Пожалуйста, примите и проголосуйте за ответ. Спасибо.