MapKit iOS 9 detailCalloutAccessory Просмотр использования

После просмотра видео WWDC 206 я предположил, что это будет тривиальная задача добавления подробного вида выноски в представление аннотации mapView.

Итак, я предполагаю, что я делаю что-то не так.

С моим представлением булавки установлено

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    let view:MKAnnotationView!

    if let dequed = routeMapView.dequeueReusableAnnotationViewWithIdentifier("pin") {
        view = dequed
    }
    else {
        view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
    }

    let x = UIView(frame: CGRectMake(0, 0, 200, 200))
    x.backgroundColor = UIColor.redColor()

    // shows the red
    //view.leftCalloutAccessoryView = x

    // working as no subtitle - but no red view
    view.detailCalloutAccessoryView = x

    view.canShowCallout = true
    return view
}

Я только получаю это

Я знаю, что представление работает, потому что если я попробую это с leftCalloutAccessoryView я получил

Я должен что-то упустить. Обратите внимание, если я просто добавлю изображение к detailCalloutAccessoryView лайк

view.detailCalloutAccessoryView = UIImage(named:"YourImageName")

Изображение там, размер правильно и т. Д.

Я просто не могу понять, как добавить свой собственный вид.

Спасибо

4 ответа

Решение

Вы должны добавить некоторые ограничения для ширины и высоты вашего вида:

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    var av = mapView.dequeueReusableAnnotationViewWithIdentifier("id")
    if av == nil {
        av = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "id")
    }

    let myView = UIView()
    myView.backgroundColor = .greenColor()

    let widthConstraint = NSLayoutConstraint(item: myView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 40)
    myView.addConstraint(widthConstraint)

    let heightConstraint = NSLayoutConstraint(item: myView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 20)
    myView.addConstraint(heightConstraint)

    av!.detailCalloutAccessoryView = myView
    av!.canShowCallout = true

    return av!
}

Мюнхен, 1972

Добавление intrinsicContentSize тоже работает.

Я провел некоторое тестирование и обнаружил, что MapKit автоматически устанавливает translatesAutoresizingMaskIntoConstraints в false, когда вы устанавливаете вид на detailCalloutAccessoryView,

На сессии WWDC 2015 "Что нового в MapKit" было сказано, что "поддерживается автоматическое размещение". Я считаю, что Apple действительно означает, что вы должны использовать автоматическую разметку?!

1. Создайте UIView и добавьте его в свои карты VC в раскадровке.

введите описание изображения здесь

Здесь вы можете установить размер, ограничения, добавить кнопки, изображения и т. Д. - макет, как вы хотите. Представления стека работают отлично в этом случае.

2. Создайте и отправьте на свой Maps VC

Управление перетаскиванием, как обычно, из вашего пользовательского представления.

@IBOutlet var customDetailView: UIView!

3. Установите detailCalloutAccessoryView для вашей булавки

Например

func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
    view.detailCalloutAccessoryView = customDetailView
}

успех

введите описание изображения здесь

Используйте UIImageView

view.detailCalloutAccessoryView = UIImageView(image:UIImage(named:"YourImageName")) 

Вы можете использовать собственный класс и переопределить intrinsicContentSize динамически изменять размер подробного представления в зависимости от его дочернего содержимого. (как намекнул @Klaas в принятом ответе)

Это может быть особенно полезно, если размер вашего представления заранее неизвестен или изменяется во время выполнения, или вы просто не хотите добавлять ограничения программно.

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

class CustomCalloutDetailView : UIView {

    @IBOutlet weak var label1: UILabel!

    @IBOutlet weak var label2: UILabel!

    @IBOutlet weak var mainStack: UIStackView!

    override var intrinsicContentSize: CGSize {
        get {
            return mainStack.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
        }
    }

    public func setLabel1(_ labelText: String) {
        self.label1.text = labelText
        self.invalidateIntrinsicContentSize()
    }
}
Другие вопросы по тегам