Skip to main content

Command Palette

Search for a command to run...

SwiftUI地图与坐标小纸条(一)

在SwiftUI中显示地图与获取当前坐标

Published
1 min read
SwiftUI地图与坐标小纸条(一)

小朋友喜欢骑车,所以就想为自己的骑行定制一个App。所以我特别准备了这个小纸条记录了今天我们上课时所列出的他获取、记录、显示坐标所需要的技术。主要是MapKit和Core Location相关。

显示一个地图

显示一个地图需要四样东西:Map是一个View来显示地图,它需要一个MKCoordinateRegion用来告诉它显示的位置(CLLocationCoordinate2D)以及缩放显示的范围(MKCoordinateSpan)。

MKCorrdinateRegion

这是一个 MKCorrdinateRegion 的声明:

@State var coordinateRegion = MKCoordinateRegion(
    center: CLLocationCoordinate2D(
        latitude: 37.330828, 
        longitude: -122.007495), 
    span: MKCoordinateSpan(
        latitudeDelta: 0.1, 
        longitudeDelta: 0.1)
)

MKCoordinateRegion需要两个参数,center是地图的中心坐标(CLLocationCoordinate2D),span是缩放的范围(MKCoordinateSpan)。

CLLocationCoordinate2D也是两个参数,latitude是纬度,longitude是经度。一个坐标的经纬度数据可以通过Google Map和Apple Map来得到,我比较喜欢在Google Map上点右键在菜单里就可以复制这个位置上的坐标信息:

image.png

MKCoordinateSpan的两个参数latitudeDelta和longitudeDelta分别代表着纬度(南北)跨度和经度(东西)跨度。你放入的数值越大,显示的范围越大、地图中的物体越小。为了对比我们先看看跨度为0.01的地图:

image.png

如果我们把它变为0.08,苹果总部就变的小小的一点了:

image.png

Map

在SwiftUI里显示一张地图还是非常简单的,MapKit提供了Map来使用,非常简单:

Map(
    coordinateRegion: $coordinateRegion ,
    showsUserLocation: true
)

Map通常会使用两个参数,coordinateRegion需要一个Binding,用来初始化显示的区域,你移动Map View里的地图时,这个数据会被改变。showsUserLocation会使用一个蓝点来显示你的当前位置。有关更多参数可以查看官方文档。整体来讲效果还是不错的:

image.png

获取位置信息

苹果官方写了一个文章Using the Standard Location Service说明如何获取位置信息。还有一个文章说明了如何更为省电的获取位置信息Using the Significant-Change Location Service。这里我主要说明下第一个方法的实现,因为官方的文档看完了,我确实花了不少时间去尝试。

这是我定义的LocationManager,实现了官方文档的说明

import CoreLocation

class LocationManager: NSObject,ObservableObject{
    static let shared = LocationManager()
    static let DefaultLocation = CLLocationCoordinate2D(latitude: 37.330828,longitude: -122.007495)
    static var currentLocation: CLLocationCoordinate2D {
        guard let location = shared.locationManager.location else {
            return DefaultLocation

        }
        return location.coordinate
    }

    private let locationManager = CLLocationManager()

    override init(){
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
}

extension LocationManager: CLLocationManagerDelegate{
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.last {
            print(location)
        }
    }
    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Location manager failed with error: \(error.localizedDescription)")
    }  

    public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("Location manager changed the status: \(status)")
    }
}

这里特别说明一下,如果你在iPad上运行这个程序,会看到基本每秒都会print(location)一下,如果你想要自动化记录,在locationManager的didUpdateLocations函数中记录是个不错的主意。如果你只是想获取当前的位置信息,就可以很方便的通过一句话来获取了:

let location = LocationManager. currentLocation

More from this blog

Https 本地服务器小纸条

最近想要尝试一下Telegram mini app,在调试时需要使用https的服务。试来试去发现在Mac下完成一个简单的HTTPS服务器还是需要点奇奇怪怪的工具的。但是整体来讲非常简单。 准备证书 主要会使用mkcert来创建证书。首先安装mkcert。 brew install mkcert brew install nss # if use Firefox 将mkcert加入到本地root CA。 mkcert -install 生成证书 本地调试可以使用localhost或127.0...

Feb 21, 20241 min read
Https 本地服务器小纸条

macOS中使用Docker发布一个python项目的小纸条

最近写了一个Telegram Bot,它可以使用语音和文字与GPT进行交互,成为了我日常重度使用的工具。从练习英语的听说读,到日常的搜索使用上都让我有了不少收获。终于,日常跑在我笔记本上的日子就要过去了,我需要它能日常跑在我的服务器上,所以准备使用Docker整个image,使得我日常的更新和服务器的迁移更为简单些。所以写下这个小纸条,方便以后自己回来查看。 安装Docker 使用Homebrew安装简单方便: brew install --cask docker Homebrew会视你的机器...

Mar 10, 20233 min read
macOS中使用Docker发布一个python项目的小纸条

老房东的纸条箱

39 posts

SwiftUI地图与坐标小纸条(一)