I am new in iOS and I implemented a MapKit with static markers from different arrays types and they are working fine, I am trying to put pins that come from shops array to be blue for example, and pins that come from community read, etc.. I have no idea about how to do this at all, they are all in red in the map and my goal is to change the color for every array of pins
here what I have tried:
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
@IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
}
I have headed some tutorials but I was not able to apply them on my example.
The basic idea is to make an annotation view type to render the correct color. So, assume for a second that you have four annotation types (see below), then you might have an annotation view type like so:
class AnnotationView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func update(for annotation: MKAnnotation?) {
switch annotation {
case is Shop: markerTintColor = .blue
case is Community: markerTintColor = .cyan
case is Cyclist: markerTintColor = .green
case is Circuit: markerTintColor = .red
default: break
}
}
}
And then you would have your view controller register that annotation view for your map view:
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(AnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
...
}
Note, when you register an annotation view type like this, you do not want to implement any mapView(_:viewFor:)
method. Since iOS 11, that delegate method is not needed/recommended any more.
Anyway, that annotation view type assumes you have four types of annotations. I'd personally make Shop
, Community
, Cyclist
and Circuit
just be annotation types, eg
class Shop: NSObject, MKAnnotation {
let id: Int
dynamic var title: String?
dynamic var subtitle: String?
dynamic var coordinate: CLLocationCoordinate2D
init(id: Int, title: String, subtitle: String? = nil, coordinate: CLLocationCoordinate2D) {
self.id = id
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
super.init()
}
}
// repeat for the other three types
And then, when I want to add them to my map:
shops.append(Shop(id: 0, title: "Shop1", coordinate: CLLocationCoordinate2D(latitude: 36.553015, longitude: 10.592774)))
shops.append(Shop(id: 0, title: "Shop2", coordinate: CLLocationCoordinate2D(latitude: 35.499414 , longitude: 10.824846)))
communities.append(Community(id: 0, title: "community1", coordinate: CLLocationCoordinate2D(latitude: 37.276943 , longitude: 10.934709)))
communities.append(Community(id: 0, title: "community2", coordinate: CLLocationCoordinate2D(latitude: 35.427828 , longitude: 9.748186)))
circuits.append(Circuit(id: 0, title: "circuit1", coordinate: CLLocationCoordinate2D(latitude: 33.773035 , longitude: 10.857805)))
cyclists.append(Cyclist(id: 0, title: "cyclist1", coordinate: CLLocationCoordinate2D(latitude: 35.785118 , longitude: 10.000871)))
mapView.addAnnotations(shops + communities + circuits + cyclists)
Alternatively, you might have one annotation type:
enum PlaceType {
case shop, community, cyclist, circuit
}
class Place: NSObject, MKAnnotation {
let id: Int
let type: PlaceType
dynamic var title: String?
dynamic var subtitle: String?
dynamic var coordinate: CLLocationCoordinate2D
init(id: Int, type: PlaceType, title: String, subtitle: String? = nil, coordinate: CLLocationCoordinate2D) {
self.id = id
self.type = type
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
super.init()
}
}
You'd then instantiate these places:
var places = [Place]()
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(AnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
places = [
Place(id: 0, type: .shop, title: "Shop1", coordinate: CLLocationCoordinate2D(latitude: 36.553015, longitude: 10.592774)),
Place(id: 0, type: .shop, title: "Shop2", coordinate: CLLocationCoordinate2D(latitude: 35.499414 , longitude: 10.824846)),
Place(id: 0, type: .community, title: "community1", coordinate: CLLocationCoordinate2D(latitude: 37.276943 , longitude: 10.934709)),
Place(id: 0, type: .community, title: "community2", coordinate: CLLocationCoordinate2D(latitude: 35.427828 , longitude: 9.748186)),
Place(id: 0, type: .circuit, title: "circuit1", coordinate: CLLocationCoordinate2D(latitude: 33.773035 , longitude: 10.857805)),
Place(id: 0, type: .cyclist, title: "cyclist1", coordinate: CLLocationCoordinate2D(latitude: 35.785118 , longitude: 10.000871))
]
mapView.addAnnotations(places)
}
And your annotation view type would then use this type
parameter:
class AnnotationView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func update(for annotation: MKAnnotation?) {
guard let annotation = annotation as? Place else { return }
switch annotation.type {
case .shop: markerTintColor = .blue
case .community: markerTintColor = .cyan
case .cyclist: markerTintColor = .green
case .circuit: markerTintColor = .red
}
}
}
This results in:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.