Ответ 1
Прежде всего следует отметить, что простейшие изменения выноски включаются путем простой настройки свойств предоставленной системы выноски, но настройки правого и левого аксессуаров (через rightCalloutAccessoryView
и leftCalloutAccessoryView
). Вы можете сделать эту конфигурацию в viewForAnnotation
.
В iOS 9 теперь у нас есть доступ к detailCalloutAccessoryView
, который заменяет субтитры выноски потенциально визуально богатым представлением, сохраняя при этом автоматическое воспроизведение пузырька выноска (с помощью автоматической компоновки это упрощает).
Например, вот выноска, в котором используется MKSnapshotter
, чтобы предоставить изображение для просмотра изображения в аксессуаре дополнительной выноски, как показано в видео WWDC 2015 Что нового в MapKit:
Вы можете добиться этого с помощью чего-то вроде:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let identifier = "MyCustomAnnotation"
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
} else {
annotationView!.annotation = annotation
}
configureDetailView(annotationView!)
return annotationView
}
func configureDetailView(annotationView: MKAnnotationView) {
let width = 300
let height = 200
let snapshotView = UIView()
let views = ["snapshotView": snapshotView]
snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[snapshotView(300)]", options: [], metrics: nil, views: views))
snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[snapshotView(200)]", options: [], metrics: nil, views: views))
let options = MKMapSnapshotOptions()
options.size = CGSize(width: width, height: height)
options.mapType = .SatelliteFlyover
options.camera = MKMapCamera(lookingAtCenterCoordinate: annotationView.annotation!.coordinate, fromDistance: 250, pitch: 65, heading: 0)
let snapshotter = MKMapSnapshotter(options: options)
snapshotter.startWithCompletionHandler { snapshot, error in
if snapshot != nil {
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
imageView.image = snapshot!.image
snapshotView.addSubview(imageView)
}
}
annotationView.detailCalloutAccessoryView = snapshotView
}
Если вы ищете более радикальную модификацию выноски или вам нужно поддерживать версии iOS до 9, она требует больше работы. Процесс влечет за собой: (а) отключение выноски по умолчанию; и (б) добавление собственного представления, когда пользователь нажимает на существующий вид аннотации (т.е. визуальный вывод на карте).
Затем возникает сложность дизайна выноски, где вы должны нарисовать все, что хотите видеть. Например. если вы хотите нарисовать пузырь, чтобы вы почувствовать прикосновение вызова, вы должны сделать это сами. Но с некоторым знакомством с тем, как рисовать фигуры, изображения, текст и т.д., Вы должны иметь возможность отображать выноску, которая достигает желаемого UX:
Просто добавьте представление в качестве подсмотра самого представления аннотации и соответствующим образом скорректируйте его ограничения:
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
let calloutView = ...
calloutView.translatesAutoresizingMaskIntoConstraints = false
calloutView.backgroundColor = UIColor.lightGrayColor()
view.addSubview(calloutView)
NSLayoutConstraint.activateConstraints([
calloutView.bottomAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0),
calloutView.widthAnchor.constraintEqualToConstant(60),
calloutView.heightAnchor.constraintEqualToConstant(30),
calloutView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: view.calloutOffset.x)
])
}
См. https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift пример создания собственного вида выноски. Это добавляет только две метки, но это иллюстрирует тот факт, что вы можете нарисовать пузырь любой желаемой фигуры, использовать ограничения, чтобы определять размер выноски и т.д.