版本记录
| 版本号 | 时间 |
|---|---|
| V1.0 | 2020.04.26 星期日 |
前言
MapKit框架直接从您的应用界面显示地图或卫星图像,调出兴趣点,并确定地图坐标的地标信息。接下来几篇我们就一起看一下这个框架。感兴趣的看下面几篇文章。
1. MapKit框架详细解析(一) —— 基本概览(一)
2. MapKit框架详细解析(二) —— 基本使用简单示例(一)
3. MapKit框架详细解析(三) —— 基本使用简单示例(二)
4. MapKit框架详细解析(四) —— 一个叠加视图相关的简单示例(一)
5. MapKit框架详细解析(五) —— 一个叠加视图相关的简单示例(二)
6. MapKit框架详细解析(六) —— 添加自定义图块(一)
7. MapKit框架详细解析(七) —— 添加自定义图块(二)
8. MapKit框架详细解析(八) —— 添加自定义图块(三)
9. MapKit框架详细解析(九) —— 地图特定区域放大和创建自定义地图annotations(一)
源码
1. Swift
首先看下工程组织结构
下面就是源码了
1. ViewController.swift
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet private var mapView: MKMapView!
private var artworks: [Artwork] = []
override func viewDidLoad() {
super.viewDidLoad()
// Set initial location in Honolulu
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
mapView.centerToLocation(initialLocation)
let oahuCenter = CLLocation(latitude: 21.4765, longitude: -157.9647)
let region = MKCoordinateRegion(
center: oahuCenter.coordinate,
latitudinalMeters: 50000,
longitudinalMeters: 60000)
mapView.setCameraBoundary(
MKMapView.CameraBoundary(coordinateRegion: region),
animated: true)
let zoomRange = MKMapView.CameraZoomRange(maxCenterCoordinateDistance: 200000)
mapView.setCameraZoomRange(zoomRange, animated: true)
mapView.delegate = self
mapView.register(
ArtworkView.self,
forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
loadInitialData()
mapView.addAnnotations(artworks)
}
private func loadInitialData() {
// 1
guard
let fileName = Bundle.main.url(forResource: "PublicArt", withExtension: "geojson"),
let artworkData = try? Data(contentsOf: fileName)
else {
return
}
do {
// 2
let features = try MKGeoJSONDecoder()
.decode(artworkData)
.compactMap { $0 as? MKGeoJSONFeature }
// 3
let validWorks = features.compactMap(Artwork.init)
// 4
artworks.append(contentsOf: validWorks)
} catch {
// 5
print("Unexpected error: \(error).")
}
}
}
private extension MKMapView {
func centerToLocation(_ location: CLLocation, regionRadius: CLLocationDistance = 1000) {
let coordinateRegion = MKCoordinateRegion(
center: location.coordinate,
latitudinalMeters: regionRadius,
longitudinalMeters: regionRadius)
setRegion(coordinateRegion, animated: true)
}
}
extension ViewController: MKMapViewDelegate {
func mapView(
_ mapView: MKMapView,
annotationView view: MKAnnotationView,
calloutAccessoryControlTapped control: UIControl
) {
guard let artwork = view.annotation as? Artwork else {
return
}
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
artwork.mapItem?.openInMaps(launchOptions: launchOptions)
}
}
2. Artwork.swift
import Foundation
import MapKit
import Contacts
class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let discipline: String?
let coordinate: CLLocationCoordinate2D
init(
title: String?,
locationName: String?,
discipline: String?,
coordinate: CLLocationCoordinate2D
) {
self.title = title
self.locationName = locationName
self.discipline = discipline
self.coordinate = coordinate
super.init()
}
init?(feature: MKGeoJSONFeature) {
// 1
guard
let point = feature.geometry.first as? MKPointAnnotation,
// 2
let propertiesData = feature.properties,
let json = try? JSONSerialization.jsonObject(with: propertiesData),
let properties = json as? [String: Any]
else {
return nil
}
// 3
title = properties["title"] as? String
locationName = properties["location"] as? String
discipline = properties["discipline"] as? String
coordinate = point.coordinate
super.init()
}
var subtitle: String? {
return locationName
}
var mapItem: MKMapItem? {
guard let location = locationName else {
return nil
}
let addressDict = [CNPostalAddressStreetKey: location]
let placemark = MKPlacemark(
coordinate: coordinate,
addressDictionary: addressDict)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = title
return mapItem
}
var markerTintColor: UIColor {
switch discipline {
case "Monument":
return .red
case "Mural":
return .cyan
case "Plaque":
return .blue
case "Sculpture":
return .purple
default:
return .green
}
}
var image: UIImage {
guard let name = discipline else { return #imageLiteral(resourceName: "Flag") }
switch name {
case "Monument":
return #imageLiteral(resourceName: "Monument")
case "Sculpture":
return #imageLiteral(resourceName: "Sculpture")
case "Plaque":
return #imageLiteral(resourceName: "Plaque")
case "Mural":
return #imageLiteral(resourceName: "Mural")
default:
return #imageLiteral(resourceName: "Flag")
}
}
}
3. ArtworkViews.swift
import Foundation
import MapKit
class ArtworkMarkerView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
// 1
guard let artwork = newValue as? Artwork else {
return
}
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
// 2
markerTintColor = artwork.markerTintColor
glyphImage = artwork.image
}
}
}
class ArtworkView: MKAnnotationView {
override var annotation: MKAnnotation? {
willSet {
guard let artwork = newValue as? Artwork else {
return
}
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
let mapsButton = UIButton(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 48, height: 48)))
mapsButton.setBackgroundImage(#imageLiteral(resourceName: "Map"), for: .normal)
rightCalloutAccessoryView = mapsButton
image = artwork.image
let detailLabel = UILabel()
detailLabel.numberOfLines = 0
detailLabel.font = detailLabel.font.withSize(12)
detailLabel.text = artwork.subtitle
detailCalloutAccessoryView = detailLabel
}
}
}
后记
本篇主要介绍了地图特定区域放大和创建自定义地图
annotations,感兴趣的给个赞或者关注~~~












网友评论