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!
}
Добавление 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()
}
}