Привет! У меня есть MapView, хочу обращаясь к ней показывать определенные места на карте по координатам сохраненным в памяти.Вопрос в том, как показать на карте опр. места по координатам. Благодарствую!
Показ мест на карте
Простой пример как сделать карту как у меня на рисунке:
-
Определяем свой MKAnnotationView и MKAnnotation
import UIKit
import MapKitclass CUAnnotationView: MKAnnotationView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if (hitView != nil) {
self.superview?.bringSubview(toFront: self)
}
return hitView
}override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
let rect = self.bounds;
var isInside: Bool = rect.contains(point)
if (!isInside) {
for view in self.subviews {
isInside = view.frame.contains(point)
if isInside {
break;
}
}
}
return isInside;
}}
-
В классе с нашей картой
-
Подписываемся под протокол MKMapViewDelegate
-
Настраиваем саму карту
@IBOutlet weak var mapView: MKMapView? { didSet { mapView?.delegate = self mapView?.mapType = .standard mapView?.isPitchEnabled = false mapView?.isRotateEnabled = false mapView?.isScrollEnabled = true mapView?.isZoomEnabled = true } }
-
На камеру добавляем наши кастомные вьюшки по координатам:
if coordinates.count > 0 {
for cam in coordinates.count {
let point = CUCamsAnnotation(coordinate: CLLocationCoordinate2D(latitude: cam.latitude,
longitude: cam.longitude))
point.image = #imageLiteral(resourceName: “web_camera_location”)
point.number = cam.number
point.address = cam.name
point.client = false
mapView?.addAnnotation(point)
}
} -
Устанавливаем регион отображения, чтоб все наши вьюшки поместились и были видны одновременно:
mapView?.fitMapViewToAnnotaionList()
с помощью такого расширения:
extension MKMapView {
func fitMapViewToAnnotaionList() -> Void {
let mapEdgePadding = UIEdgeInsets(top: 40, left: 40, bottom: 40, right: 40)
var zoomRect:MKMapRect = MKMapRectNull
for index in 0..<self.annotations.count {
let annotation = self.annotations[index]
let aPoint:MKMapPoint = MKMapPointForCoordinate(annotation.coordinate)
let rect:MKMapRect = MKMapRectMake(aPoint.x, aPoint.y, 0.1, 0.1)
if MKMapRectIsNull(zoomRect) {
zoomRect = rect
} else {
zoomRect = MKMapRectUnion(zoomRect, rect)
}
}
self.setVisibleMapRect(zoomRect, edgePadding: mapEdgePadding, animated: true)
}
}
-
Сообщаем, что используем не пин, а свою кастомную вьюшку с нашим изображением:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }
var annotationView = self.mapView?.dequeueReusableAnnotationView(withIdentifier: “Pin”)
if annotationView == nil{
annotationView = CUAnnotationView(annotation: annotation, reuseIdentifier: “Pin”)
annotationView?.canShowCallout = false
}
else { annotationView?.annotation = annotation }
annotationView?.image = #imageLiteral(resourceName: “web_camera_location”)
return annotationView
}
Чтобы сделать такую вьюшку для детализации:
- Создадим xib-файл и настроим нашу вьюшку как душе угодно. Можно использовать что угодно… лейблы, имиджи, свичи, кнопки и так далее
Ну и сам классы для нее
import UIKit
class CUDetailCamView: UIView {
@IBOutlet weak var address: UILabel?
@IBOutlet weak var image: UIImageView?
@IBOutlet weak var backView: UIView? {
didSet {
backView?.layer.borderColor = #colorLiteral(red: 0.9925034642, green: 0.8121734858, blue: 0, alpha: 1).cgColor
backView?.layer.borderWidth = 0.35
backView?.layer.cornerRadius = backView!.frame.size.height / 2
backView?.layer.masksToBounds = true
}
}
var number: String!
var client: Bool!
}
В контроллере с камерой осталось добавить пару методов и все будет работать:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if view.annotation is MKUserLocation { return }
let detailAnnotation = view.annotation as! CUCamsAnnotation
let views = Bundle.main.loadNibNamed("CUDetailCamView", owner: nil, options: nil)
let detailtView = views?[0] as! CUDetailCamView
detailtView.address?.text = detailAnnotation.address
detailtView.number = detailAnnotation.number
detailtView.client = detailAnnotation.client
let button = UIButton(frame: detailtView.address!.frame)
button.addTarget(self, action: #selector(CUMapsController.showStream(sender:)), for: .touchUpInside)
detailtView.addSubview(button)
detailtView.center = CGPoint(x: view.bounds.size.width / 2, y: -detailtView.bounds.size.height * 0.52)
view.addSubview(detailtView)
mapView.setCenter((view.annotation?.coordinate)!, animated: true)
}
func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) {
if view.isKind(of: CUAnnotationView.self) {
for subview in view.subviews {
subview.removeFromSuperview()
}
}
}
Извиняюсь за то что поднимаю тему
Не могли бы добавить в решение реализацию протокола MKAnnotation ?
А лучше проект с этим всем)))
Решение представлено выше. Там все понятно объясняется. Если есть конкретные вопросы - задавайте.